2013-01-18 64 views
4

我有一個表,看起來像這樣:的MySQL通過UPDATE整合重複數據的記錄/刪除

mysql> SELECT * FROM Colors; 
╔════╦══════════╦════════╦════════╦════════╦════════╦════════╦════════╗ 
║ ID ║ USERNAME ║ RED ║ GREEN ║ YELLOW ║ BLUE ║ ORANGE ║ PURPLE ║ 
╠════╬══════════╬════════╬════════╬════════╬════════╬════════╬════════╣ 
║ 1 ║ joe  ║ 1  ║ (null) ║ 1  ║ (null) ║ (null) ║ (null) ║ 
║ 2 ║ joe  ║ 1  ║ (null) ║ (null) ║ (null) ║ 1  ║ (null) ║ 
║ 3 ║ bill  ║ 1  ║ 1  ║ 1  ║ (null) ║ (null) ║ 1  ║ 
║ 4 ║ bill  ║ (null) ║ 1  ║ (null) ║ 1  ║ (null) ║ (null) ║ 
║ 5 ║ bill  ║ (null) ║ 1  ║ (null) ║ (null) ║ (null) ║ (null) ║ 
║ 6 ║ bob  ║ (null) ║ (null) ║ (null) ║ 1  ║ (null) ║ (null) ║ 
║ 7 ║ bob  ║ (null) ║ (null) ║ (null) ║ (null) ║ (null) ║ 1  ║ 
║ 8 ║ bob  ║ 1  ║ (null) ║ (null) ║ (null) ║ (null) ║ (null) ║ 
╚════╩══════════╩════════╩════════╩════════╩════════╩════════╩════════╝ 

我想運行一個UPDATEDELETE這將找到並刪除重複和鞏固記錄,從而使我們將以此結束。

mysql> SELECT * FROM Colors; 
╔════╦══════════╦═════╦════════╦════════╦════════╦════════╦════════╗ 
║ ID ║ USERNAME ║ RED ║ GREEN ║ YELLOW ║ BLUE ║ ORANGE ║ PURPLE ║ 
╠════╬══════════╬═════╬════════╬════════╬════════╬════════╬════════╣ 
║ 1 ║ joe  ║ 1 ║ (null) ║ 1  ║ (null) ║ 1  ║ (null) ║ 
║ 3 ║ bill  ║ 1 ║ 1  ║ 1  ║ 1  ║ (null) ║ 1  ║ 
║ 6 ║ bob  ║ 1 ║ (null) ║ (null) ║ 1  ║ (null) ║ 1  ║ 
╚════╩══════════╩═════╩════════╩════════╩════════╩════════╩════════╝ 

我知道我可以很容易地通過腳本做到這一點,但在學習和理解的MySQL更好的利益,我想學習如何做到這一點使用純SQL

+0

我想你是說如果你想刪除記錄,而不是'UPDATE',那就是說'DELETE'。 – FrankPl

+0

FrankPI,你是對的。我已經更新了這個問題以包含'DELETE'。 –

回答

3

這只是一個投影。它不更新表格或刪除一些數據。

SELECT MIN(ID) ID, 
     Username, 
     MAX(Red) max_Red, 
     MAX(Green) max_Green, 
     MAX(Yellow) max_Yellow, 
     MAX(Blue) max_Blue, 
     MAX(Orange) max_Orange, 
     MAX(Purple) max_Purple 
FROM Colors 
GROUP BY Username 

UPDATE

,如果你真的要刪除這些記錄,你需要先運行UPDATE語句,然後才能刪除記錄

UPDATE Colors a 
     INNER JOIN 
     (
      SELECT MIN(ID) min_ID, 
        Username, 
        MAX(Red) max_Red, 
        MAX(Green) max_Green , 
        MAX(Yellow) max_Yellow, 
        MAX(Blue) max_Blue, 
        MAX(Orange) max_Orange, 
        MAX(Purple) max_Purple 
      FROM Colors 
      GROUP BY Username 
     ) b ON a.ID = b.Min_ID 
SET  a.Red = b.max_Red, 
     a.Green = b.max_Green, 
     a.Yellow = b.max_Yellow, 
     a.Blue = b.max_Blue, 
     a.Orange = b.max_Orange, 
     a.Purple = b.max_Purple 

然後,你現在可以刪除的記錄,

DELETE a 
FROM Colors a 
     LEFT JOIN 
     (
      SELECT MIN(ID) min_ID, 
        Username 
      FROM Colors 
      GROUP BY Username 
     ) b ON a.ID = b.Min_ID 
WHERE b.Min_ID IS NULL 
+0

看到我的更新':D' –

+0

使用我的建議下面,你不需要一箇中間的更新,但只有一個DELETE – FrankPl

1

你真的需要更新基礎表嗎?如果沒有(和你只是想在你的例子所示的結果集),你可以簡單地組表:

SELECT MIN(ID)  AS ID, 
     Username AS Username, 
     MAX(Red) AS Red, 
     MAX(Green) AS Green, 
     MAX(Yellow) AS Yellow, 
     MAX(Blue) AS Blue, 
     MAX(Orange) AS Orange, 
     MAX(Purple) AS Purple 
FROM  Colors 
GROUP BY Username 

看到它的sqlfiddle

0
DELETE FROM Colors c1 
WHERE EXISTS (SELECT 1 
       FROM Colors c2 
       WHERE c1.Username = c2.Username 
       AND ((c1.Red IS NULL AND c2.Red IS NULL) OR c1.Red = c2.Red ) 
       AND ((c1.Green IS NULL AND c2.Green IS NULL) OR c1.Green = c2.Green) 
       AND ((c1.Yellow IS NULL AND c2.Yellow IS NULL) OR c1.Yellow = c2.Yellow) 
       AND ((c1.Blue IS NULL AND c2.Blue IS NULL) OR c1.Blue = c2.Blue ) 
       AND ((c1.Orange IS NULL AND c2.Orange IS NULL) OR c1.Orange = c2.Orange) 
       AND ((c1.Purple IS NULL AND c2.Purple IS NULL) OR c1.Purple = c2.Purple) 
       AND c2.ID < c1.ID 
      ) 

的零點使這一點更爲複雜,因爲NULL = NULL是不正確的,但在SQL未知。如果您有0和1,則可以省略顏色條件中OR之前的部分。