2010-05-03 81 views
2

我在測試數據庫中有一張表,表明某人在運行INSERT腳本進行設置時顯然有點觸發 - 很開心。模式如下所示:如何刪除表中的重複記錄?

ID UNIQUEIDENTIFIER 
TYPE_INT SMALLINT 
SYSTEM_VALUE SMALLINT 
NAME VARCHAR 
MAPPED_VALUE VARCHAR 

它應該有幾十行。它大約有20萬個,其中大部分都是重複的,其中TYPE_INT,SYSTEM_VALUE,NAME和MAPPED_VALUE全都相同,ID不相同。

現在,我大概可以創建一個腳本來清理這個在內存中創建臨時表的腳本,使用INSERT .. SELECT DISTINCT來獲取原始表的所有唯一值,然後將所有內容都複製回來。但有沒有一種更簡單的方法來做到這一點,比如DELETE查詢在WHERE子句中有什麼特別之處?

回答

4

你不給你的表名,但我認爲這樣的事情應該工作。只是離開恰好具有最低ID的記錄。你可能想先用ROLLBACK進行測試!

BEGIN TRAN 
DELETE <table_name> 
FROM <table_name> T1 
WHERE EXISTS(
SELECT * FROM <table_name> T2 
WHERE  
T1.TYPE_INT = T2.TYPE_INT AND 
T1.SYSTEM_VALUE = T2.SYSTEM_VALUE AND 
T1.NAME = T2.NAME AND 
T1.MAPPED_VALUE = T2.MAPPED_VALUE AND 
T2.ID > T1.ID 
) 

SELECT * FROM <table_name> 

ROLLBACK 
2
WITH Duplicates(ID , TYPE_INT, SYSTEM_VALUE, NAME, MAPPED_VALUE) 
AS 
(
SELECT Min(Id) ID TYPE_INT, SYSTEM_VALUE, NAME, MAPPED_VALUE 
FROM T1 
GROUP BY TYPE_INT, SYSTEM_VALUE, NAME, MAPPED_VALUE 
HAVING Count(Id) > 1 
) 
DELETE FROM T1 
WHERE ID IN (
SELECT T1.Id 
FROM T1 
INNER JOIN Duplicates 
ON T1.TYPE_INT = Duplicates.TYPE_INT 
AND T1.SYSTEM_VALUE = Duplicates.SYSTEM_VALUE 
AND T1.NAME = Duplicates.NAME 
AND T1.MAPPED_VALUE = Duplicates.MAPPED_VALUE 
AND T1.Id <> Duplicates.ID 
) 
3

這裏是一個偉大的文章:Deleting duplicates,基本上使用此模式:

WITH q AS 
     (
     SELECT d.*, 
       ROW_NUMBER() OVER (PARTITION BY id ORDER BY value) AS rn 
     FROM t_duplicate d 
     ) 
DELETE 
FROM q 
WHERE rn > 1 

SELECT * 
FROM t_duplicate