2016-07-13 48 views
1

我知道,從mysql刪除重複往往是在這裏討論。但是在我的情況下,這個解決方案沒有任何問題。刪除從大型MySQL地址數據庫重複

所以,我有地址數據幾乎像這樣的DB:

ID; Anrede; Vorname; Nachname; Strasse; Hausnummer; PLZ; Ort; Nummer_Art; Vorwahl; Rufnummer 

ID是主鍵和獨特的。

,我有例如entrys這樣的:

1;Herr;Michael;Müller;Testweg;1;55555;Testhausen;Mobile;;67890 
2;Herr;Michael;Müller;Testweg;1;55555;Testhausen;Fixed;045678;877656 

不同******中國都沒有問題,因爲他們是不相關的我。所以我只想刪除姓氏,街道和郵編中的副本。在這種情況下,ID 1或ID 2.哪一個都不重要。

我試圖刪除它實際上是這樣的:

DELETE db 

FROM Import_Daten db, 
    Import_Daten dbl 

WHERE db.id > dbl.id AND 
     db.Lastname = dbl.Lastname AND 
     db.Strasse = dbl.Strasse AND 
     db.PLZ = dbl.PLZ; 

並插入到一個複製表:

INSERT INTO Import_Daten_1 

SELECT MIN(db.id), 
     db.Anrede, 
     db.Firstname, 
     db.Lastname, 
     db.Branche, 
     db.Strasse, 
     db.Hausnummer, 
     db.Ortsteil, 
     db.Land, 
     db.PLZ, 
     db.Ort, 
     db.Kontaktart, 
     db.Vorwahl, 
     db.Durchwahl 

FROM Import_Daten db, 
     Import_Daten dbl 

WHERE db.lastname = dbl.lastname AND 
     db.Strasse = dbl.Strasse And 
     db.PLZ = dbl.PLZ; 

完整的表格包含了10Mio行。大小實際上是我的問題。該MySQL運行在MacBook上的MAMP服務器上,具有1,5GHZ和4GB RAM。所以不是很快。 SQL語句在phpmyadmin中運行。其實我沒有其他系統的可能性。

回答

0

您可以添加一個新列,例如uq並使之成爲UNIQUE

ALTER TABLE Import_Daten 
ADD COLUMN `uq` BINARY(16) NULL, 
ADD UNIQUE INDEX `uq_UNIQUE` (`uq` ASC); 

當做到這一點,你可以執行UPDATE這樣的查詢

UPDATE IGNORE Import_Daten 
SET 
    uq = UNHEX(
      MD5(
      CONCAT(
       Import_Daten.Lastname, 
       Import_Daten.Street, 
       Import_Daten.Zipcode 
      ) 
      ) 
     ) 
WHERE 
    uq IS NULL; 

一旦所有條目更新,並再次執行查詢時,所有重複將有uq字段的值= NULL並可以刪除。然後

結果是:

0 row(s) affected, 1 warning(s): 1062 Duplicate entry...

對於新添加的行總是創建uq哈希和,並考慮使用這個作爲主鍵一次,所有條目都是唯一的。

+0

Phantastic!真的快速工作!非常感謝! – swapfile

+0

爲防止插入重複項,我們可以在(姓氏,Strasse,PLZ)字段集上添加唯一索引。 – olegsv

+0

第一次應用此解決方案將刪除所有重複記錄。它不會留下重複記錄的一個副本。 – olegsv

1

您可以編寫一個stored procedure,每次選擇一個不同的數據塊(例如通過兩個值之間的rownumber)並僅從該範圍內刪除。通過這種方式,您將逐步刪除您的副本

+0

謝謝。我沒有使用存儲過程的經驗。我會看看這個。但是,如果j只是「清理」行號範圍內的一個範圍,並且數據沒有排序,它就無法工作,或者? – swapfile

+0

@Chrisko - 添加了一些文檔的鏈接 –

1

一個更有效的兩表解決方案可以看起來像下面。 我們只能存儲我們真正需要刪除的數據,而且只能存儲包含重複信息的字段。 我們假設我們正在尋找姓氏,分支,Haushummer字段中的重複數據。

創建表來保存重複數據

DROP TABLE data_to_delete;

填充數據,我們需要刪除表(我假設所有的領域都VARCHAR(255)型)

CREATE TABLE data_to_delete ( id BIGINT COMMENT 'this field will contain ID of row that we will not delete', cnt INT, Lastname VARCHAR(255), Branche VARCHAR(255), Hausnummer VARCHAR(255) ) AS SELECT min(t1.id) AS id, count(*) AS cnt, t1.Lastname, t1.Branche, t1.Hausnummer FROM Import_Daten AS t1 GROUP BY t1.Lastname, t1.Branche, t1.Hausnummer HAVING count(*)>1 ;

現在讓我們刪除重複的數據,並留下所有重複集合中只有一個記錄

DELETE Import_Daten FROM Import_Daten LEFT JOIN data_to_delete ON Import_Daten.Lastname=data_to_delete.Lastname AND Import_Daten.Branche=data_to_delete.Branche AND Import_Daten.Hausnummer = data_to_delete.Hausnummer WHERE Import_Daten.id != data_to_delete.id;

DROP TABLE data_to_delete;

+0

謝謝。這也是有效的。但Bernhard版本對於進一步進口來說速度更快,速度更快。 – swapfile

+0

@Chrisko我同意它的速度更快。爲防止插入重複記錄,您可以使用唯一索引。此外,我恐怕在現有數據上應用此解決方案時,您將刪除所有重複記錄,並且不會留下重複系列的一個副本。 – olegsv