SQL中刪除重復(fù)數(shù)據(jù)問題
本文轉(zhuǎn)載自微信公眾號(hào)「SQL數(shù)據(jù)庫開發(fā)」,作者丶平凡世界 。轉(zhuǎn)載本文請(qǐng)聯(lián)系SQL數(shù)據(jù)庫開發(fā)公眾號(hào)。
需求分析
數(shù)據(jù)庫中存在重復(fù)記錄,刪除保留其中一條(是否重復(fù)判斷基準(zhǔn)為多個(gè)字段)
解決方案
碰到這樣的問題我們先分解步驟來看
- 創(chuàng)建測(cè)試數(shù)據(jù)
- 找到重復(fù)的數(shù)據(jù)
- 刪除重復(fù)的數(shù)據(jù)并且保留一行
創(chuàng)建測(cè)試數(shù)據(jù)
我們創(chuàng)建一個(gè)人員信息表并在里面插入一些重復(fù)的數(shù)據(jù)。
- CREATE TABLE [dbo].[Person](
- [ID] [INT] IDENTITY(1,1) NOT NULL,
- [Name] [VARCHAR](20) NULL,
- [Age] [INT] NULL,
- [Address] [VARCHAR](20) NULL,
- [Sex] [CHAR](2) NULL
- );
- SET IDENTITY_INSERT [dbo].[Person] ON;
- INSERT INTO [dbo].[Person] (ID,Name,Age,Address,Sex)
- VALUES
- ( 1, '張三', 18, '北京路18號(hào)', '男' ),
- ( 2, '李四', 19, '北京路29號(hào)', '男' ),
- ( 3, '王五', 19, '南京路11號(hào)', '女' ),
- ( 4, '張三', 18, '北京路18號(hào)', '男' ),
- ( 5, '李四', 19, '北京路29號(hào)', '男' ),
- ( 6, '張三', 18, '北京路18號(hào)', '男' ),
- ( 7, '王五', 19, '南京路11號(hào)', '女' ),
- ( 8, '馬六', 18, '南京路19號(hào)', '女' );
- SET IDENTITY_INSERT [dbo].[Person] OFF;
(提示:可以左右滑動(dòng)代碼)
建立好測(cè)試數(shù)據(jù)如下:
我們發(fā)現(xiàn)除了自增長(zhǎng)ID不同以為,有幾條其他字段都重復(fù)的數(shù)據(jù)出現(xiàn),符合我們的需求。
找出重復(fù)的數(shù)據(jù)
- SELECT MAX(ID) ID ,
- Name,Age,Address,Sex
- FROM dbo.Person
- GROUP BY Name,Age,Address,Sex
- HAVING COUNT(1)>1
HAVING將分組后統(tǒng)計(jì)出來的數(shù)量大于1的數(shù)據(jù)行,就是我們要找的重復(fù)數(shù)據(jù):
上面用Max函數(shù)或者M(jìn)in函數(shù)均可,只是為了保證取出來的數(shù)據(jù)的唯一性。
刪除重復(fù)的數(shù)據(jù)
其實(shí)我們數(shù)據(jù)庫中最后要保留的結(jié)果就是第二步中查詢出來的數(shù)據(jù),我們把其他的數(shù)據(jù)刪除即可。怎么刪除呢?我們使用ID來排除。
- DELETE FROM Person
- WHERE EXISTS
- (
- SELECT * FROM (
- SELECT
- MAX(ID) ID,
- Name,Age,Address,Sex
- FROM dbo.Person
- GROUP BY Name,Age,Address,Sex
- HAVING COUNT(1)>1) T
- WHERE Person.Name=T.Name
- AND Person.Age=T.Age
- AND Person.Address=T.Address
- AND Person.Sex=T.Sex
- AND Person.ID<T.ID--如果上面使用MIN函數(shù),這里就要改成>
- )
執(zhí)行完后重新查詢Person表結(jié)果如下:
馬六因?yàn)橹挥幸粭l記錄,所以沒有參與去重,直接顯示。
今天的案例分享結(jié)束,小伙伴們可以自己動(dòng)手嘗試一下,興許工作中也會(huì)遇到類似問題。如果你在公眾中遇到一些有趣的問題也可以發(fā)送給我。