Mysql按条件更新相同的表列,按列更新组
这是Mysql表,我想如下设置版本列。版本列有数百万条记录需要更新Mysql按条件更新相同的表列,按列更新组,mysql,sql,stored-functions,Mysql,Sql,Stored Functions,这是Mysql表,我想如下设置版本列。版本列有数百万条记录需要更新 File_id |file_name | type | flag | original_file_id | version 1 |abc.jpg | FILE | RENAMED | 1 | 1 3 |folder1 | FOLDER | RENAMED | 3 | null 5 |fol
File_id |file_name | type | flag | original_file_id | version
1 |abc.jpg | FILE | RENAMED | 1 | 1
3 |folder1 | FOLDER | RENAMED | 3 | null
5 |folder1 | FOLDER | null | 3 | null
7 |abc1.jpg | FILE | null | 1 | 2
9 |abc1.jpg | FILE | DELETED | 1 | 2
11 |abc.jpg | FILE | MOVED | 1 | 3
13 |abc.jpg | FILE | null | 1 | 4
15 |xyz.jpg | FILE | null | 6 | 1
17 |xyz.jpg | FILE | DELETED | 6 | 1
19 |xyz.jpg | FILE | null | 6 | 2
我想将版本设置为如上所述。对于第一个文件,其中文件id=原始文件id,则版本=1。如果删除标志,则将以前的版本设置为版本2。对于其他重命名、移动的增量版本。但它应仅更新文件,而不更新文件夹。您可以使用此查询:
UPDATE FILES
SET version = CASE
WHEN original_file_id = File_id THEN File_id
WHEN flag = 'DELETED' THEN (SELECT F1.version-F2.version FROM FILES F1, FILES t2 WHERE F1.File_id = F2.File_id -1)
WHEN flag = 'RENAMED' THEN ((SELECT F1.version-F2.version FROM FILES F1, FILES t2 WHERE F1.File_id = F2.File_id -1)+1)
WHEN flag = 'MOVED' THEN ((SELECT F1.version-F2.version FROM FILES F1, FILES t2 WHERE F1.File_id = F2.File_id -1)+1);
您可以使用以下查询:
update files
join
( select f1.file_id,
count(f2.file_id) + count(distinct forg.file_id) as version
from files f1
left outer join files forg
on f1.original_file_id = forg.file_id
and f1.original_file_id = forg.original_file_id
and forg.flag = 'DELETED'
left outer join files f2
on f1.original_file_id = f2.original_file_id
and f1.file_id >= f2.file_id
and coalesce(f2.flag,'') <> 'DELETED'
and coalesce(f2.type,'') <> 'FOLDER'
where coalesce(f1.type,'') <> 'FOLDER'
group by f1.file_id
) fileversions
on fileversions.file_id = files.file_id
set files.version = fileversions.version
where coalesce(files.type, '') <> 'FOLDER';
它将增加每个原始\u文件\u id-group中的版本,除非它有一个标志='Deleted'。类型为“Folder”的所有行都将被忽略且不会更新
第一个file_id=original_file_id的文件将获得版本1,即使它的标志为“deleted”,在这种情况下,下一个未删除的文件将获得版本2
查询不会检查您的数据是否损坏,例如,是否存在文件id=原始文件id的文件,或者是否存在文件id为文件id<原始文件id的文件
如果要在合理的时间内完成,您需要索引原始文件id或原始文件id、文件id。表中的主键列是什么?@jimmacoulay抱歉,我已更新了我的问题文件id为primarykey@GordonLinoff不修订版取决于标志和原始文件id。版本与原始文件id不一致。现在检查。您是否了解了?我了解了,但我通过更改表列中添加的类型列再次更新了我的问题。请立即检查此项。我只需要更新文件,而不需要更新文件夹。因此,对于文件id,它不总是增量1。在每个where条件之后提供**和F1。type='FILE'**。你能做到吗?或者您需要再次执行整个查询?这很好,我可以添加条件,其中type=FILE,但F1.FILE\u id=F2.FILE\u id-1有效吗?因为您无法确保下一个文件\u id。假设abc.jpg file\u id为3,那么下一个文件\u id可以是60。因此,对于这里,F1.file\u id=F2.file\u id-1,我可以做什么?您的查询依赖于每个组的连续文件\u id,没有间隙,中间没有其他文件组。我认为这不是一个有效的假设。感谢您的帮助。但我有一些疑问。1如果组的第一个文件具有该标志,则其版本设置为0。这不应是预期的,因为第一个文件总是获取版本1,而不是其他任何内容。2如果某个地方的原始文件记录已损坏,那么该如何处理?与originalfileid 50一样,该组有3个文件,文件id为51、52、53,原始文件id为50,但originalfileid和文件id为50的文件已损坏。1如果删除第一个条目,会发生什么情况?你说一个被删除的文件应该得到之前的版本,它不存在2我不明白你的意思,你能给出一个例子和你想要的结果吗?但一般来说:如果您的数据不干净,您就不能期望得到干净的结果。你是说像原始文件那样的东西吗?即使文件\u id=6不存在,我的查询也会为您提供问题中关于文件\u id=15的第1版的确切输出。忘记损坏数据的第2个条件。但必须存在第1个条件,即文件id=originalfileid的文件,其版本始终为1。例如,在我的例子中,带有文件ID 1和15的表文件是第一个文件,原始文件ID总是与FLAG无关,因为无论在什么之后都需要考虑FLAG。所有的东西都是完美的,除非这个条件版本必须从1开始。它不应该是零。所以假设在你的示例数据中,FielyID的1, 7和9将删除该标志,文件ID 1、7、9和11的版本是:1、1、1、2?对的