SQL Server中如何删除重复记录,确保ColB无重复且记录唯一?
解决方法
你的问题出在原SQL的逻辑上:按ColA分区并按ColB排序取第一条,会导致每个ColA都保留ColB最小的那条记录,最终所有结果的ColB全为1,完全没考虑ColB的唯一性要求。
要实现每个ColA保留一条,且所有ColB值不重复的目标,需要从ColB的唯一性入手,建立ColA和ColB的一一映射关系,以下是两种可行方案:
方案1:固定规则映射(按顺序匹配)
适合需要按固定顺序(如ColA/ColB字典序)建立映射的场景:
WITH cola_ranked AS ( -- 给所有唯一的ColA分配序号 SELECT DISTINCT ColA, ROW_NUMBER() OVER (ORDER BY ColA) AS cola_id FROM table_1 ), colb_ranked AS ( -- 给所有唯一的ColB分配序号 SELECT DISTINCT ColB, ROW_NUMBER() OVER (ORDER BY ColB) AS colb_id FROM table_1 ), target_records AS ( -- 建立ColA和ColB的一一对应关系 SELECT cr.ColA, cb.ColB FROM cola_ranked cr JOIN colb_ranked cb ON cr.cola_id = cb.colb_id ) -- 删除不在目标映射中的记录 DELETE FROM table_1 WHERE (ColA, ColB) NOT IN (SELECT ColA, ColB FROM target_records);
效果说明
- 若
ColA和ColB的唯一值数量相等:每个ColA对应唯一的ColB,完美满足需求。 - 若
ColA数量多于ColB:超出ColB数量的ColA会被全部删除(因为没有对应的唯一ColB)。 - 若
ColB数量多于ColA:仅匹配与ColA数量相等的ColB值,其余ColB不会被选中。
方案2:随机映射(避免固定顺序)
如果需要随机分配ColA和ColB的对应关系,避免总是选中最小的ColB,只需将排序规则改为随机:
WITH cola_ranked AS ( SELECT DISTINCT ColA, ROW_NUMBER() OVER (ORDER BY NEWID()) AS cola_id FROM table_1 ), colb_ranked AS ( SELECT DISTINCT ColB, ROW_NUMBER() OVER (ORDER BY NEWID()) AS colb_id FROM table_1 ), target_records AS ( SELECT cr.ColA, cb.ColB FROM cola_ranked cr JOIN colb_ranked cb ON cr.cola_id = cb.colb_id ) DELETE FROM table_1 WHERE (ColA, ColB) NOT IN (SELECT ColA, ColB FROM target_records);
针对16条临时记录的处理(4个ColA对应4个ColB)
假设插入4个ColA值,每个ColA对应4个ColB值(共16条记录),以上两种方案都会自动建立4组唯一的ColA-ColB映射:
- 方案1会按
ColA和ColB的字典序匹配(如A-1、B-2、C-3、D-4)。 - 方案2会随机匹配(如
A-3、B-1、C-4、D-2)。
最终都会保留4条记录,每个ColA一条,所有ColB值无重复。
内容的提问来源于stack exchange,提问作者Early Bird
相关产品推荐
相关产品推荐

