MSSQL删除表中已有的重复数据,保留一条数据

来源:互联网 发布:nginx 前后端分离 编辑:程序博客网 时间:2024/06/11 06:32

MSSQL删除重复数据,保留一条数据

今天接到一个小需求,对一张数据表增加一个多字段(比如a,b,c三个字段)唯一索引。编写好创建脚本后,高高兴兴的拿去跑,结果出错了,提示有重复键值,一检查才发现,数据表里有很多按照a,b,c字段重复数据啊,悲了个剧,问了问领导,领导说,重复的可以删掉,保留一条就行了,领导这话说的轻松,问领导当初创建表的时候怎么没考虑到这个需求啊,当然了,问也白问,领导噼里啪啦说一通,还是要删,删就删吧。考试写删除的脚本。。。。

步骤如下
第一步当然是先搞一个模拟的表了,搞一些测试数据进去,直接在服务器上搞,领导肯定得疯,哈哈。。。

  • 创建张模拟表,让ID自增长主要是删除时用到这个,不再用rowid了
    CREATE TABLE [dbo].[deletetest](    [ID] [int] IDENTITY(1,1) NOT NULL,    [Time] [datetime] NOT NULL,    [Msec] [int] NOT NULL,    [SID] [int] NOT NULL,    [CID] [int] NOT NULL,    [DID] [int] NOT NULL,    [SFlag] [tinyint] NOT NULL,    [C1] [int] NOT NULL,    [C2] [int] NOT NULL    )
  • 制造一些数据进去,代码就不写了,造出多条SID,CID,DID重复的数据出来。结果如下图:
    这里写图片描述
    数据中包括3组sid,cid,did相同的数据。

  • 写个查询脚本查询出重复数据,结果和上图一样,因为所有的数据都是重复的。。。
    查询脚本:

select a.* from deletetest a join (select sid,cid,did from deletetest group by sid,cid,did having count(*)>1) b on a.sid=b.sid and a.cid=b.cid and a.did=b.did
  • 结果查询出来了,下面就是删除了。对于重复的数据,只保留一条,其余的都删除,我们就保留ID最小的那一条。
    删除语句:
delete from DeleteTest where id in (select a.id from deletetest a join (select sid,cid,did from detetetest group by sid,cid,did having count(*)>1) b on b.sid=a.sid and b.cid=a.cid and b.did=a.did and id not in (select min(id) from detetetest group by sid,cid,did having count(*)>1))
  • 删除后在查询全表,结果如下:
    这里写图片描述

    从查询结果可以看出,重复的数据已经被删掉,且保留了一条ID最小的数据。

  • 使用这个脚本把字段调整一下,在项目数据库里跑一把,成功删除重复数据,然后再创建索引,成功!

PS:今天突然发现想到一种更简单的删除方法,上面所说的删除方法思路被查询重复数据误导了,太复杂了。
其实使用not in的方式删除就OK了,语句如下:

delete DeteteTest where id not in (select min(id) from DeteteTest group by sid,cid,did)
1 0
原创粉丝点击