SQL Server 删除重复数据的四种有效方法
在处理 SQL Server 数据库时,经常遇到因系统设计缺陷或数据导入导致的重复记录问题。根据重复性质的不同(完全重复或部分关键字段重复),本文整理了四种高效的去重解决方案,涵盖从传统游标到现代 CTE 的多种实现思路。
方法一:使用 Cursor 游标批量删除
这种方法适用于通过特定主键字段判定重复的情况。它利用事务型游标遍历重复的主键,并利用 SET ROWCOUNT 动态控制每次删除的数量,确保只保留一条原始记录。
- 声明变量:创建整型变量存储主键值和重复计数。
- 构建游标:按主字段分组查询,筛选出重复次数大于1的组。
- 循环执行:在游标每行中计算需删除的行数(总行数 - 1),执行删除后移动至下一组。
declare @max integer,@id integer
declare cur_rows cursor local for select 主字段,count(*) from 表名 group by 主字段 having count(*) > 1
open cur_rows
fetch cur_rows into @id,@max
while @@fetch_status=0
begin
select @max = @max -1
set rowcount @max
delete from 表名 where 主字段 = @id
fetch cur_rows into @id,@max
end
close cur_rows
set rowcount 0
方法二:全字段重复的去重
当需要处理的重复记录意味着所有字段的值完全一致时,处理起来非常直接。这类问题通常源于缺乏唯一约束的设计,解决时需先清洗数据,后续建议增加索引防范。
第1步:提取不重复数据
利用 DISTINCT 关键字直接从原表中获取无重复的记录集。
select distinct * from tableName
第2步:重建表格保留单条记录
若必须物理删除磁盘上的冗余数据,可使用临时表中转:复制不重复数据到新表 → 删掉旧表 → 将新表重命名/导回为旧表 → 删除临时表。
select distinct * into #Tmp from tableName
drop table tableName
select * into tableName from #Tmp
drop table #Tmp
注:生产环境执行此类高危操作前,请务必进行完整数据库备份。
方法三:基于 RowNumber 的唯一性过滤
这是目前处理部分字段重复(如仅要求 Name 和 Address 唯一)最推荐的方法。通过自增列 IDENTITY 辅助排序,可以灵活地“保留第一条”或“保留最后一条”。此处以保留首次出现的记录为例。
- 建立临时映射:加入自增列
autoID存入临时表#Tmp。 - 确定保留项:按指定重复字段(如
Name)分组,选取最小的autoID作为保留依据并存入#Tmp2。 - 剔除多余数据:反向关联
#Tmp,只查出存在于#Tmp2中的记录,即为最终结果。
select identity(int,1,1) as autoID, * into #Tmp from tableName
select min(autoID) as autoID into #Tmp2 from #Tmp group by Name
select * from #Tmp where autoID in(select autoID from #tmp2)
此 SQL 执行后返回的结果即为符合去重要求的干净数据集。实际开发中,如果需要真正删除,可将第三个 SELECT 替换为带 WHERE autoID NOT IN (SELECT autoID FROM #Tmp2) 的 DELETE 语句。
方法四:Access 等数据库去重技巧
对于不支持 IDENTITY 函数的 Access 数据库,或者习惯使用简单子句的操作者,可以采用内联比较的方式:找出重复字段中出现多次的值,然后排除掉非最小 ID(即非首次出现)的记录。
delete from 表名 where 重复字段名 in (select 重复字段名 from 表名 group by 重复字段名 having count(重复字段名) > 1) and id not in (select min(id) from 表名 group by 重复字段名 having count(重复字段名 )>1)
该方法直观易懂,将复杂的分组逻辑浓缩在一行中,适合快速清理小规模脏数据。只需将占位符替换为实际的表名、去重字段名及主键名称即可运行。
简要总结
面对 SQL Server 的重复数据顽疾,用户应根据实际需求选择最优解。若涉及多字段逻辑判断且追求性能,推荐使用带有 ROW_NUMBER() 分析的现代窗口函数替代传统的游标写法;而对于简单的全量比对,临时表法最为稳妥。为了避免反复陷入数据修复的困境,核心原则仍在于事前规范化表结构设计并引入唯一索引约束。以上就是SQL Server中删除重复数据方法的详细内容,更多关于数据库优化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













