因程序缺陷導致重複數據是常見問題,不僅佔用空間還可能破壞約束。針對不同重複類型,提供三種成熟解法:
DECLARE @max INT, @id INT
DECLARE cur CURSOR LOCAL FOR
SELECT 主鍵, COUNT(*) FROM 表名 GROUP BY 主鍵 HAVING COUNT(*) > 1
OPEN cur
FETCH cur INTO @id, @max
WHILE @@FETCH_STATUS = 0
BEGIN
SET @max = @max - 1
SET ROWCOUNT @max
DELETE FROM 表名 WHERE 主鍵 = @id
FETCH cur INTO @id, @max
END
CLOSE cur
SET ROWCOUNT 0
適用於有明確主鍵、需逐組處理的場景。
-- 查詢去重結果
SELECT DISTINCT * FROM tableName
-- 物理刪除重複(保留一條)
SELECT DISTINCT * INTO #Tmp FROM tableName
DROP TABLE tableName
SELECT * INTO tableName FROM #Tmp
DROP TABLE #Tmp
根因通常是缺乏唯一索引,補建唯一索引可一勞永逸。
-- 假設 Name、Address 為業務鍵
SELECT IDENTITY(INT,1,1) AS autoID, * INTO #Tmp FROM tableName
SELECT MIN(autoID) AS autoID INTO #Tmp2 FROM #Tmp GROUP BY Name, Address
SELECT * FROM #Tmp WHERE autoID IN (SELECT autoID FROM #Tmp2)
利用臨時身份列標記行序,保留每組業務鍵的首條記錄。最終 SELECT 可顯式列出業務列剔除 autoID。