2013-04-07 3 views
7

J'ai une table:Le moyen le plus efficace de supprimer toutes les lignes dupliquées de la table?

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

Je veux supprimer toutes lignes contenant des doublons par foo colonne de sorte que la table devrait ressembler à ceci:

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

Quel est le le plus efficace façon de le faire?

Répondre

9

Vous pouvez joindre une table à partir d'une sous-requête qui renvoie uniquement foo en utilisant LEFT JOIN. Les lignes qui n'ont pas un match sur la sous-requête seront supprimés comme vous le souhaitez, par exemple

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 

Pour améliorer les performances, ajoutez un index sur la colonne Foo.

ALTER TABLE tableName ADD INDEX(foo) 
+0

Cela fonctionne parfait, mais il est trop lent (j'ai une très grande table). –

+0

ajouter un index sur la colonne pour qu'il s'exécute plus rapidement, par exemple, 'ALTER TABLE tableName ADD INDEX (foo) 'et voir les performances. –

+0

Merci, mais je l'ai déjà fait. Mais c'est la façon la plus rapide de le faire, de toute façon, je vois. –

8

En utilisant 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) 

En utilisant IN:

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

Si je suis correct, la version existante que vous avez écrite ici est significativement plus rapide que la version in. Dans cet esprit, y a-t-il un argument en faveur de la version in? – usumoio

Questions connexes