数据库重复行删除问题:SQL误删全部记录求正确方案
解决删除重复记录时误删全部相关记录的问题
我完全懂你踩的这个坑——原来的SQL把所有存在重复a3_loan的记录都一锅端了,而你真正想要的是每个a3_loan只保留a3_seq最小的那条记录,删掉其他重复项对吧?
给你两种可靠的解决方案,按需选择:
方法1:基于MIN()子查询保留最小序列
这个方法逻辑直接,通过子查询找出每个a3_loan对应的最小a3_seq,然后删除不在这个保留集合里的记录:
DELETE FROM ldataphd.srvalt3 WHERE (a3_loan, a3_seq) NOT IN ( SELECT a3_loan, MIN(a3_seq) FROM ldataphd.srvalt3 GROUP BY a3_loan );
方法2:用窗口函数灵活处理复杂场景
如果之后你需要更复杂的重复判断(比如按多个字段分组、保留最新记录等),窗口函数是更通用的方案:
WITH duplicate_records AS ( SELECT a3_loan, a3_seq, -- 按a3_loan分组,a3_seq升序排序,每组第一条标记为1 ROW_NUMBER() OVER (PARTITION BY a3_loan ORDER BY a3_seq ASC) AS row_num FROM ldataphd.srvalt3 ) DELETE FROM ldataphd.srvalt3 USING duplicate_records WHERE ldataphd.srvalt3.a3_loan = duplicate_records.a3_loan AND ldataphd.srvalt3.a3_seq = duplicate_records.a3_seq -- 删除每组中除第一条外的其他重复记录 AND duplicate_records.row_num > 1;
关键提醒!
执行删除前一定要先验证!把DELETE换成SELECT,看看要删除的记录是不是你预期的:
比如方法1可以先跑:
SELECT * FROM ldataphd.srvalt3 WHERE (a3_loan, a3_seq) NOT IN ( SELECT a3_loan, MIN(a3_seq) FROM ldataphd.srvalt3 GROUP BY a3_loan );
确认这些是你要删掉的重复项后,再执行DELETE操作,避免再次误删数据。
内容的提问来源于stack exchange,提问作者Karthick Ricky
相关产品推荐
相关产品推荐

