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)