SQL Server 删除重复记录,只保留一条记录

本文详细介绍了在SQLServer2012环境下,如何在已有重复记录的情况下,通过自定义SQL语句来实现删除重复记录的操作,以满足建立多字段唯一约束的需求。

        有张表格之前没有设计关键字段的唯一约束,导致有时候执行插入操作时不小心执行了多次就出现了重复记录,后面重新加入唯一约束,由于已经有了重复记录,无法添加,需要先删除重复记录。

        看了网上的一些删除重复记录的方法(好像都是转载于同一篇文章,至少看了十几篇都是同样的内容),其中一个链接:http://blog.csdn.net/anya/article/details/6407280

        自己现在是需要建立多字段唯一约束(非主键),用文中的方法是不行的,反正在SQL Server 2012中是无法通过的。改写了下,如下:

1、查询重复记录:

SELECT * FROM dbo.Table T
WHERE EXISTS (SELECT 字段1, 字段2, 字段3 FROM dbo.TableSign WHERE 字段1= T.字段1 AND 字段2= T.字段2
AND 字段3 = T.字段3 GROUP BY 字段1, 字段2, 字段3 HAVING COUNT(*) > 1)
AND T.SelfID NOT IN (SELECT MIN(SelfID) FROM dbo.Table GROUP BY 字段1, 字段2, 字段3 HAVING COUNT(*) > 1)

其中:字段1, 字段2, 字段3指需要建立唯一约束的三个字段,SelfID指表Table中的一个自增字段。


2、删除重复记录,只保留SelfID最小的记录,也就是第一次插入的记录:

DELETE FROM dbo.TableSign
WHERE SelfID IN

(SELECT SelfID FROM dbo.Table T

WHERE EXISTS (SELECT 字段1, 字段2, 字段3 FROM dbo.TableSign WHERE 字段1= T.字段1 AND 字段2= T.字段2
AND 字段3 = T.字段3 GROUP BY 字段1, 字段2, 字段3 HAVING COUNT(*) > 1)
AND T.SelfID NOT IN (SELECT MIN(SelfID) FROM dbo.Table GROUP BY 字段1, 字段2, 字段3 HAVING COUNT(*) > 1))


SQL Server 中,去除重复数据保留一条可以采用以下几种方法: ### 使用 ROW_NUMBER() 窗口函数 通过 `ROW_NUMBER()` 窗口函数为每一行分配一个行号,按重复列的条件分组,然后删除行号大于 1 的行。示例代码如下: ```sql WITH CTE AS ( SELECT code, timePoint, ROW_NUMBER() OVER (PARTITION BY code, TimePoint ORDER BY (SELECT 0)) AS rn FROM table_name ) DELETE FROM CTE WHERE rn > 1; ``` 此代码中,`PARTITION BY` 用于按条件分组,`rn > 1` 用于删除所有重复的行,只保留每组中的第一行 [^1]。 ### 基于多个字段判断重复 同样使用 `ROW_NUMBER()` 窗口函数,以多个字段作为分组依据。示例如下: ```sql WITH cte AS ( SELECT col1, col2, ROW_NUMBER() OVER(PARTITION BY col1, col2 ORDER BY (SELECT 0)) AS rn FROM talbe_name ) DELETE FROM cte WHERE rn > 1; ``` 该代码以 `col1` 和 `col2` 作为分组依据,删除重复行,只保留每组的第一行 [^2]。 ### 按特定字段判断重复 如果根据单个字段判断重复,可以先查找重复记录,再删除多余的重复记录,只保留 `rowid` 最小的记录。示例如下: ```sql -- 查找表中多余的重复记录 select * from people where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1); -- 删除表中多余的重复记录 delete from people where peopleName in (select peopleName from people group by peopleName having count(peopleName) > 1) and peopleId not in (select min(peopleId) from people group by peopleName having count(peopleName)>1); ``` 若要根据多个字段判断重复,示例代码如下: ```sql -- 查找表中多余的重复记录(多个字段) select * from vitae a where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1); -- 删除表中多余的重复记录(多个字段) delete from vitae a where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1) and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1); ``` 上述代码分别实现了根据单个字段和多个字段判断重复记录,并删除多余记录,只保留最小 `rowid` 的记录 [^3]。 ### 按指定列删除重复数据 示例代码如下: ```sql WITH CTE AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY CB_ChildBaseInfoID,AdminId,CONVERT(varchar(100), CreateTime, 23) ORDER BY (SELECT NULL)) AS rn FROM LT_VisionScree(表) ) DELETE FROM CTE WHERE rn > 1; ``` 此代码以 `CB_ChildBaseInfoID`、`AdminId` 和转换后的 `CreateTime` 作为分组依据,删除重复行,只保留每组的第一行 [^5]。 ### 查询方式保留一条记录 ```sql select * From (Select Row_Number() Over(Partition By [Mnumber] order By [Mnumber]) As RowNumber,* From MCCESS)T Where T.RowNumber = 1; ``` 该代码通过 `ROW_NUMBER()` 函数对 `Mnumber` 列进行分组,查询时只保留每组 `RowNumber` 为 1 的记录 [^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值