sql - 如何更新具有重复 ID 的引用表?
问题描述
我正在使用postgresql。要删除表中的重复项,我使用此查询:
DELETE FROM dups a USING (
SELECT MIN(ctid) as ctid, key
FROM dups
GROUP BY key HAVING COUNT(*) > 1
) b
WHERE a.key = b.key
AND a.ctid <> b.ctid
参考:https ://stackoverflow.com/a/12963112/4940278
但是,有一个表格说明ref_table
了dups.id
它们的引用位置。在删除重复项之前,我需要更新另一个表。用重复的 id 更新引用表的查询是什么,这样就不会丢失数据?
例如:
表 1,说dups
id key
1 Luna
2 Hermione
3 Luna
表 2,说ref_table
id dups_id data
1 2 Auror
2 1 Researcher
现在删除重复项的查询将删除 dups 表中 id 为 1 的记录,因为它是重复项。但是,该记录在 中被引用ref_table
,因此我需要使用将要保留的记录来更新它。
即)表1应该变成:
id key
2 Hermione
3 Luna
表 2 应变为:
id dups_id data
1 2 Auror
2 3 Researcher
解决方案
使用 CTE 识别 dups 中维护的行,然后更新 ref 行,以便 FK 仅指向它们,最后删除不再需要的行。
with keeper as -- identify dups rows to be kept
( select id, key
, max(id) over(partition by key) mid
from dups)
, u as -- update ref so dup_id references only those being kept
( update ref r
set dup_id = (select k.mid
from keeper k
join dups d
on (k.id=d.id)
where r.dup_id != k.mid
and r.dup_id = k.id
)
)
delete -- final target remove dups rows no lnger needed
from dups d
where d.id not in (select mid from keeper);
推荐阅读
- scala - 在scala中有两个变量的for循环
- tensorflow - TFRecordDataset 和 FixedLengthRecordDataset 有什么区别?
- python - 使用 python 对传感器数据进行排序的高性能方法
- java - 有没有办法使用 BufferedReader 将值直接接受到 List 中?
- forms - 第一个或第二个输入表单需要
- java - java long to byte[] (primitive long, not Long to byte array) - 两个实现之间不相等
- javascript - 根据Javascript中的条件从数据表中提取所有行的最佳方法是什么
- python - 我已经被这个错误困住了一个星期。OSError: [Errno 9] 错误的文件描述符
- machine-learning - Grover算法在机器学习中的应用
- python - Python Matrix 正确检查对角线和水平线以赢得比赛