1. 程式人生 > >MySQL-去重留一

MySQL-去重留一

問題:

  去除MySQL中重複的記錄,僅保留其中一條。本例中cname為重複項,而cid為primary key。

嘗試解決:

  使用程式碼:

DELETE FROM t_customer
WHERE cname in
    (
    SELECT cname FROM t_customer GROUP BY cname HAVING count(cname)>1
    )
AND cid NOT IN
    (
    SELECT min(cid) cid FROM t_customer GROUP BY cname HAVING count(cname)>
1 )

  程式碼思路:

    設定2個條件,1是查出cname相同的記錄裡的cname值,2是查出cname相同的記錄裡cid最小的一項記錄的cid值,然後據此進行刪除cname重複的記錄,保留其中cid最小的記錄。

  執行以後發現:

    報錯:[HY000][1093] You can't specify target table 't_customer' for update in FROM clause
    報錯原因:(找了幾篇部落格看來的)大意是:不能在同一條語句中對某個欄位進行判斷的同時,又對其進行update操作。有博主還提到“這個問題只出現於MySQL,MSSQL和Oracle不會出現此問題”(未驗證過,在此只是提一句)

最後解決:

  1種程式碼:

DELETE FROM t_customer
WHERE cname in
    (
    SELECT cname FROM
                      (
                      SELECT cname FROM t_customer GROUP BY cname HAVING count(cname)>1
                      ) t1
    )
AND cid NOT IN
    (
    SELECT cid FROM
                    (
                    SELECT min(cid) cid FROM t_customer GROUP BY cname HAVING count(cname)>1
                    ) t2
    )

   思路:

    將之前的2個查詢結果先暫存為t1和t2,然後從這2個臨時集合中查詢出cname和cid作為刪除條件

  第2中程式碼:

    看其他的部落格看到的:

DELETE t_customer
FROM
     t_customer,
     (
     SELECT min(cid) cid, cname
     FROM t_customer
     GROUP BY cname
     HAVING count(cname)>1
     )t
WHERE t_customer.cname=t.cname
AND t_customer.cid>t.cid;

     執行以後也得到了想要的結果。