2010-10-08 40 views
3

我需要從數據庫中刪除重複的行。我可以用簡單的sql查詢嗎?如果沒有,請給我看一些快速算法來做到這一點。從數據庫中刪除重複的行

實施例:

id| field_one | field_two | 
1 | 0000000 | 11111111 | 
2 | 2222222 | 33333333 | 
3 | 2222222 | 33333333 | 
4 | 4444444 | 55555555 | 

我需要刪除行編號爲2(或3,無論,它們是相等的,但不是兩者)。 感謝您的幫助

回答

4
delete from the_table where id in 
    (select max(id) from the_table 
     group by field_one, field_two 
     having count(*) > 1) 

正如在評論中指出,如果連續出現三次,這將無法正常工作。直到它停止刪除的東西,你可以反覆運行這個(重)查詢,或等待一個更好的答案...

+0

+1 - 正在發佈完全相同的答案。速度計數! – codingbadger 2010-10-08 07:51:38

+1

如果你有三次同一行? – CristiC 2010-10-08 07:53:13

+0

感謝超級快速回答:)這應該工作。 – Scorpil 2010-10-08 07:53:32

3

首先選擇所有不同行,然後刪除其他的人:

DELETE FROM MyTable 
WHERE id NOT IN 
     (
     SELECT MAX(id) FROM MyTable 
     GROUP BY field_one, field_two 
    ) 
+0

+1。這可以處理多次重複的行。如果大多數行不重複,它可能會非常慢。根據當時的情況,我認爲在你的兵工廠裏有兩個問題都是很好的選擇。 – Thilo 2010-10-08 07:59:38

+0

當有很多重複項時,另一種有用的方法是將「好」行復制到工作/登臺表中,然後截斷舊的表。這避免了碎片化。 – Thilo 2010-10-08 08:02:12

1

蒂洛的答案是一個有用的,它只是讓你想要的東西。無論如何,如果你有很多線路,它可能會佔用很多時間,因爲算法的複雜度是正方形的。如果我是問誰,我會選擇Thilo的答案作爲最佳答案,無論如何,我只是想給你另一種選擇:如果你有很多線路,那麼另一種可能性是:

創建一個新表,建立一個用於列組合的UNIQUE INDEX :(field_one,field_two)並將第一個表的內容複製到新的表中。然後刪除舊的表名並將新的表名重命名爲舊的表名。

就是這樣。

2
set rowcount 1 
delete userTbl1 from userTbl1 a1 where (select count(UName) from userTbl1 a2 where a2.UName =a1.UName)>1 
while @@rowcount > 0 
delete userTbl1 from userTbl1 a1 where (select count(UName) from userTbl1 a2 where a2.UName =a1.UName)>1 
set rowcount 0