【发布时间】:2020-09-14 03:03:57
【问题描述】:
我有一个带有 id 的表,我们现在添加了一个新字段,我们从外部来源计算唯一性,这让我们意识到我们实际上在数据库中有重复:
主表
id | unique_id | ...
---|------------
4 | A |
5 | A
6 | B
我们可以看到:5 实际上是 4 的副本,因为它们都有相同的 unique_id。
现在需要清理一下。
很遗憾,我不能简单地删除那些重复项 (5),因为其他表依赖于它:
其他表 (OtherTable.main_id REFERENCES MainTable.id)
id | main_id | ...
---|------------
1 | 4 | Blah
2 | 5
3 | 6
现在我要清理重复的,在这里
UPDATE OtherTable SET main_id = 5 WHERE main_id=4
如何在有效的更新中做到这一点?
我尝试使用相同的unique_id 简单地更新对第一个引用的每个引用,但这并没有在一天内完成。
UPDATE "OtherTable" SET "main_id" = (SELECT "id" FROM "MainTable" WHERE "unique_id" = (SELECT "unique_id" FROM "MainTable" WHERE "id" == "OtherTable"."main_id") LIMIT 1)
如果有帮助,MainTable 包含大约 750,000 个条目,OtherTable 包含 12,000,000 行。
可能那是因为那些三重选择一的效率很低。
对于删除重复项的简单部分(在我完成将引用更改为第一个类似的引用之后)我发现这个查询工作得足够快:
DELETE FROM MainTable
WHERE id IN
(SELECT id
FROM
(SELECT id,
ROW_NUMBER() OVER( PARTITION BY unique_id
ORDER BY id ) AS row_num
FROM MainTable ) t
WHERE t.row_num > 1 );
但是我需要一种方法来更新对未删除重复项的引用。
【问题讨论】:
-
请不要混淆更新和删除。你想要什么?
-
@wildplasser 更新所有引用重复项的表,然后删除重复项。
标签: postgresql