2014-10-10 48 views
1

我有一個重複的發現者查詢...轉換重複查找查詢所有下降,但帶有最新的記錄

SELECT 
    Author, Name, TrackNum, title_id, COUNT(*) 
FROM 
    db.table 
GROUP BY 
    Author, Name, TrackNum, title_id 
HAVING 
    COUNT(*) > 1 

它返回那些重複的記錄,以及有多少計數。

我想擴大這個範圍,這樣它就會刪除每個副本的最新版本。我想我們可以使用iddatetime字段,我可以在表中找到哪些記錄。還是有另一種方式?

編輯:我走了一半......

SELECT 
    * 
FROM 
    db.table 
GROUP BY 
    Author, Name, TrackNum, title_id 
HAVING 
    COUNT(*) > 1 
ORDER BY 
    Name, TrackNum 

以上似乎表明每個副本的一個副本。當我在工作臺中刪除它們時,我只剩下剩餘的最新唯一記錄。我只想進一步自動化這一步。此外,這不包括兩個以上相同的記錄。

回答

1

提出的解決方案

# 
# Step 01) Create Temp Key Tables 
# 
CREATE TABLE KeysToKeep 
(
    id INT NOT NULL, 
    PRIMARY KEY (id) 
); 
CREATE TABLE KeysToDrop LIKE KeysToKeep; 
# 
# Step 02) Collect All id values you want to Keep 
# 
INSERT INTO KeysToKeep 
    SELECT id FROM 
    (SELECT MAX(id) id,Author, Name, TrackNum, title_id 
    FROM db.table GROUP BY Author, Name, TrackNum, title_id) A 
; 
# 
# Step 03) Collect All id values you want to Drop 
# 
INSERT INTO KeysToDrop 
SELECT A.id FROM db.table A LEFT JOIN KeysToKeep USING (id) WHERE B.id IS NULL; 
# 
# Step 04) Do the Mass Delete 
# 
DELETE A.* FROM db.table A INNER JOIN KeysToDrop B USING (id); 
# 
# Step 05) Remove Temp Key Tables 
# 
DROP TABLE KeysToKeep; 
DROP TABLE KeysToDrop; 

提出的解決方案(短版)

# 
# Step 01) Create Temp Key Table 
# 
CREATE TABLE KeysToKeep 
(
    id INT NOT NULL, 
    PRIMARY KEY (id) 
); 
# 
# Step 02) Collect All id values you want to Keep 
# 
INSERT INTO KeysToKeep 
    SELECT id FROM 
    (SELECT MAX(id) id,Author, Name, TrackNum, title_id 
    FROM db.table GROUP BY Author, Name, TrackNum, title_id) A 
; 
# 
# Step 03) Do the Mass Delete 
# 
DELETE A.* FROM db.table A LEFT JOIN KeysToKeep B USING (id) WHERE B.id IS NULL; 
# 
# Step 04) Remove Temp Key Table 
# 
DROP TABLE KeysToKeep; 

提出的解決方案(偏執版)

# 
# Step 01) Create Temp Key Table 
# 
CREATE TABLE KeysToKeep 
(
    id INT NOT NULL, 
    PRIMARY KEY (id) 
); 
# 
# Step 02) Collect All id values you want to Keep 
# 
INSERT INTO KeysToKeep 
    SELECT id FROM 
    (SELECT MAX(id) id,Author, Name, TrackNum, title_id 
    FROM db.table GROUP BY Author, Name, TrackNum, title_id) A 
; 
# 
# Step 03) Copy the Tables to Keep to Another Temp Table 
# 
CREATE TABLE db.table_new LIKE db.table; 
INSERT INTO db.table_new 
SELECT A.* FROM db.table A INNER JOIN KeysToKeep B USING (id); 
# 
# Step 04) Swap New and Old Tables 
# 
ALTER TABLE db.table RENAME db.table_old; 
ALTER TABLE db.table_new RENAME db.table; 
# 
# Step 05) Remove Temp Key Table 
# 
DROP TABLE KeysToKeep; 
# 
# Step 06) Drop the Old Table If the Content of db.table is Correct 
# 
DROP TABLE db.table_old; 

EPILOGUE

在前兩種情況下s,請檢查KeysToKeep和/或KeysToDrop以確保它們是保留或丟棄的關鍵。在最後一種情況下,如果您確定,請刪除表格db.table_old。如果你不確定,你可以這樣回滾:

ALTER TABLE db.table RENAME db.table_new; 
ALTER TABLE db.table_old RENAME db.table; 

給它一個嘗試!

+0

感謝您的精彩迴應。我現在正在測試環境中完成這項工作。我嘗試了偏執版。首先,我用db名稱替換了所有db的出現。我得到一個語法錯誤,所以刪除了一個額外的';'。然後我得到一個錯誤:錯誤代碼:1248.每個派生表都必須有自己的別名。有任何想法嗎? – 2014-10-11 22:05:14

+0

我忘了在步驟02中放置一個別名。請再試一次... – RolandoMySQLDBA 2014-10-13 16:52:11

+0

確定試過,現在我得到這個錯誤...'你的SQL語法錯誤;請檢查與您的MySQL服務器版本相對應的手冊,以便在'INSERT INTO KeysToKeep'附近使用正確的語法。選擇ID號碼 (第12行的SELECT MAX(id)id,作者,名稱,T'注意我刪除了一個額外的分號我之前提到過(第7行) – 2014-10-13 20:19:28