2013-04-07 17 views
7

Mam tabeli:Najbardziej skuteczny sposób na usunięcie wszystkich zduplikowanych wierszy z tabeli?

| foo | bar | 
+-----+-----+ 
| a | abc | 
| b | def | 
| c | ghi | 
| d | jkl | 
| a | mno | 
| e | pqr | 
| c | stu | 
| f | vwx | 

Chcę usunąć wszystkie wiersze zawierające duplikaty przez foo kolumny tak, że tabela powinna wyglądać następująco:

| foo | bar | 
+-----+-----+ 
| b | def | 
| d | jkl | 
| e | pqr | 
| f | vwx | 

Jaki jest najskuteczniejszym sposób to zrobić?

Odpowiedz

9

Możesz dołączyć do tabeli z podzapytania, który zwraca tylko unikalny foo przy użyciu LEFT JOIN. Wiersze, które nie mają spotkanie na podkwerendzie zostaną usunięte, jak to potrzebne, np

DELETE a 
FROM TableName a 
     LEFT JOIN 
     (
      SELECT foo 
      FROM TableName 
      GROUP BY Foo 
      HAVING COUNT(*) = 1 
     ) b ON a.Foo = b.Foo 
WHERE b.Foo IS NULL 

celu poprawienia wydajności, dodać indeks na kolumnie Foo.

ALTER TABLE tableName ADD INDEX(foo) 
+0

Działa to idealny, ale jest zbyt powolny (mam bardzo duży stół). –

+0

dodaj indeks do kolumny, aby działał szybciej, na przykład: ALTER TABLE tableName ADD INDEX (foo) 'i zobacz wydajność. –

+0

Dzięki, ale już to zrobiłem. Ale widzę, że jest to najszybszy sposób, aby to zrobić. –

8

Korzystanie EXISTS:

DELETE a 
    FROM TableName a 
WHERE EXISTS (SELECT NULL 
       FROM TableName b 
       WHERE b.foo = a.foo 
      GROUP BY b.foo 
       HAVING COUNT(*) > 1) 

Korzystanie IN:

DELETE a 
    FROM TableName a 
WHERE a.foo IN (SELECT b.foo 
        FROM TableName b 
       GROUP BY b.foo 
       HAVING COUNT(*) > 1) 
+0

Jeśli mam rację, istniejąca wersja, którą tu napisałeś, jest znacznie szybsza niż wersja w wersji. Mając to na uwadze, czy istnieje jakiś argument dotyczący tej wersji? – usumoio