2012-10-28 124 views
2

我有一些需要刪除冗餘數據的MySQL表。例如:選擇具有重複數據的行

id email   date  data... 
1 [email protected] 2012-01-01 my_data 
2 [email protected] 2012-01-01 my_data 
3 [email protected] 2012-01-02 my_data 
4 [email protected] 2012-01-02 my_data (redundant) 
5 [email protected] 2012-01-02 my_data 

我需要刪除多餘的行,但我想先選擇它們。我發現這個StackOverflow上,但它需要的電子郵件地址

SELECT * 
FROM `my_table` 
WHERE `id` IN (SELECT `id` 
       FROM `my_table` 
       where `email` = '[email protected]' 
       group by `date` 
       HAVING count(*) > 1) 

我可以使用什麼樣的查詢像上面在嵌入式查詢不使用WHERE預選賽,所以我能做到這一點下跌的所有電子郵件地址?

該查詢可以是一個SELECT查詢。我不介意在PHPMyAdmin中手動刪除行。

+0

''' '我可以像上面那樣在嵌入式查詢中不使用WHERE限定符來使用什麼查詢,這樣我就可以執行所有電子郵件地址了? '''通過這個你是否意味着所有重複的,只是保持一個副本? –

+0

是的,刪除所有重複的行,但保留原始行 –

回答

7
DELETE FROM tableName 
WHERE ID NOT IN 
(
    SELECT minID 
    FROM 
    (
     SELECT email, date, MIN(id) minID 
     FROM tableNAme 
     GROUP BY email, date 
    ) x 
) 

或通過使用JOIN

DELETE a 
FROM tableName a 
    LEFT JOIN (
      SELECT minID 
      FROM (
        SELECT email, DATE, MIN(id) minID 
        FROM tableNAme 
        GROUP BY email, DATE 
        ) y 
      ) x 
      ON a.ID = x.minID 
WHERE x.minID IS NULL; 

下面的查詢只SELECT每個電子郵件日期重複的行

SELECT a.* 
FROM tableName a 
     LEFT JOIN 
     ( 
     SELECT minID 
     FROM 
     (
      SELECT email, date, MIN(id) minID 
      FROM tableNAme 
      GROUP BY email, date 
     )y 
     ) x ON a.ID = x.minID 
WHERE x.minID IS NULL 
+1

出色的工作... :) – Sami

+2

約翰值得雙倍積分,因爲他完美地回答了它,並將我介紹給SQL小提琴!真棒! –

0

另一種方法是計算日期列的出現次數爲每個電子郵件地址在你的桌子上:

SELECT `email`, `date`, COUNT(*) FROM `my_table` GROUP BY `date`, `email` HAVING COUNT(*) > 1 

+------------------+---------------------+----------+ 
| email   | date    | COUNT(*) | 
+------------------+---------------------+----------+ 
| [email protected] | 2012-01-02 00:00:00 |  2 | 
+------------------+---------------------+----------+ 
+0

但是,我必須爲每個電子郵件地址執行此操作。 –

+0

@EricCope我從您的示例數據中輸出了這個查詢輸出,但是如果您有很多電子郵件,它會自動顯示所有電子郵件,每天操作時count> 1。您還必須記住要刪除的行的限制,即在上面的計數爲2的情況下,所以您只能刪除一行,而不是兩個(!)。因此,在一個非常安全的方面,你可以重寫我的查詢爲: '選擇電子郵件,日期,計數(*)作爲'計數', CONCAT('刪除我的電子郵件地址='',電子郵件' ''LIMIT',(COUNT(*) - 1),';')AS'query' FROM my_table GROUP BY date,email HAVING COUNT(*)> 1; – GregD