【mysql】刪除重複數據

最近因爲發現數據庫中的表有髒數據,需要維護。這些髒數據就是重複數據,需要將其刪除。

可能因爲你在建表的時候考慮欠佳,需要爲表裏面的幾個字段建立一個(聯合)唯一索引,但是沒有建立,而由於不止一個寫的程序在往表裏面insert數據,造成數據的重複~~

現在需要刪除這些重複數據,看了看網上前輩們寫的例子,大多數不能用,rowid也出來了,而mysql中是沒有rowid的。

 

現假設有一張t_test表,主鍵字段爲id,還有date,time,cnt1,cnt,cnt3三個字段。假設date,time組合起來規定只能有一條記錄(即需要爲date,time建立聯合唯一索引)。表中數據如下:


 

可以看出:表中數據明顯有不滿足條件的重複數據。

 

我們先查詢出有哪些重複數據(按date, time兩個字段):

SELECT * FROM t_test WHERE (DATE, TIME) IN(SELECT DATE,TIME FROM t_test GROUP BY DATE, TIME HAVING COUNT(1)>1);

 結果如下:



 嘗試使用網上的方法刪除:

DELETE FROM t_test a WHERE (a.date, a.time) IN(SELECT DATE,TIME FROM t_test GROUP BY DATE, TIME HAVING COUNT(1)>1)
AND rowid NOT IN(SELECT MIN(rowid) FROM t_test GROUP BY DATE, TIME HAVING COUNT(1)>1)

 根本行不通,因爲rowid在MySQL裏面是不存在的,這不同於Oracle。。

還需注意的一點是:mysql中不支持在delete語句裏使用表別名,所以無法進行自連接來刪除表中的記錄!

 

解決方法:使用一箇中間臨時表過渡~~

首先,建立一個臨時表如下:

CREATE TEMPORARY TABLE tmp AS SELECT MIN(id) FROM t_test GROUP BY DATE,TIME 

 查看臨時表tmp的內容:

SELECT * FROM tmp

 得到:



 這張臨時表記錄了重複記錄裏id最小的主鍵,以及沒有重複記錄的主鍵信息。

接下來,刪除不在裏面的記錄即可:

DELETE FROM t_test WHERE id NOT IN(SELECT * FROM tmp) 

 檢查下現在的記錄:

SELECT * FROM t_test

 發現:



 發現,記錄終於“乾淨”了。。重複性的記錄被成功刪除了!

當然比較保險的做法是建表時期就給date和time字段加上一個聯合索引。或者刪除重複記錄之後再alter table加上一個聯合索引即可。

  • 5546d00e-b3df-3380-832b-a652a4fcb89a-thumb.png
  • 大小: 12.9 KB
  • 43fdd9a3-734e-3c64-996e-241a6191f133-thumb.png
  • 大小: 9.3 KB
  • 8ec38036-0898-38bb-8a91-9bea36318f1f-thumb.png
  • 大小: 1.5 KB
  • 6fadf8eb-f77a-395c-8e95-cc1713d3f845-thumb.png
  • 大小: 7.2 KB
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章