SQL Server 2008中如何合并两表并基于主键去重?
解决SQL Server 2008中两表合并按主键去重的问题
嘿,我来帮你搞定这个SQL Server 2008里的表合并去重需求!根据你说的“对比主键(PK)去除重复数据”,我分两种常见场景给你具体的实现方案:
方案1:优先保留指定表的记录(比如保留TableA的数据)
如果遇到主键重复的情况,你想保留其中一个表(比如TableA)的记录,丢弃另一个表(TableB)的重复项,有两种简单的实现方式:
方法A:用LEFT JOIN快速实现
这个方法性能不错,而且SQL Server 2008完全支持:
-- 先取TableA的所有记录,再追加TableB中不存在于TableA的记录 SELECT * FROM TableA UNION ALL SELECT b.* FROM TableB b LEFT JOIN TableA a ON b.PK = a.PK WHERE a.PK IS NULL
解释:LEFT JOIN会找出TableB中所有主键不在TableA里的记录,再和TableA的全部记录合并,完美避免主键重复。
方法B:用窗口函数实现灵活优先级
如果你需要更灵活的规则(比如按某个字段排序决定保留哪条重复记录),可以用ROW_NUMBER()窗口函数:
WITH CombinedData AS ( SELECT *, -- 给同主键的记录排优先级,TableA标记为1(优先保留),TableB为2 ROW_NUMBER() OVER (PARTITION BY PK ORDER BY SourceTable) AS RowNum FROM ( -- 合并两个表,并标记来源 SELECT *, 'TableA' AS SourceTable FROM TableA UNION ALL SELECT *, 'TableB' AS SourceTable FROM TableB ) AS UnionedData ) -- 只保留每组主键中优先级最高的那条 SELECT PK, Column1, Column2 -- 这里替换成你实际需要的列(排除SourceTable和RowNum) FROM CombinedData WHERE RowNum = 1
你可以修改ORDER BY后面的字段,比如换成CreateDate DESC,就能保留最新的那条记录,非常灵活。
方案2:任意保留一条重复记录(不指定优先级)
如果不在乎保留哪个表的记录,只要每个主键只出现一次,可以用这个简化版:
WITH CombinedData AS ( SELECT *, -- 按主键分组,随机取一条(实际执行可能按存储顺序) ROW_NUMBER() OVER (PARTITION BY PK ORDER BY (SELECT NULL)) AS RowNum FROM ( SELECT * FROM TableA UNION ALL SELECT * FROM TableB ) AS UnionedData ) SELECT PK, Column1, Column2 -- 替换成你的实际列 FROM CombinedData WHERE RowNum = 1
小提示(针对SQL Server 2008)
- 优先用
UNION ALL代替UNION,因为UNION会自动排序去重,性能比UNION ALL差很多; - 如果要把合并结果存入新表,只需要在SELECT前加
INSERT INTO 新表名 (列1, 列2, ...); - 确保你的源表主键本身没有重复数据,否则需要先清理源表哦。
内容的提问来源于stack exchange,提问作者sridhar
相关产品推荐
相关产品推荐

