2013-04-07 4 views
7

У меня есть таблица:Самый эффективный способ удаления всех повторяющихся строк из таблицы?

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

Я хочу удалить все строки, содержащие повторяющиеся по foo столбца так, что таблица должна выглядеть следующим образом:

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

Что такое наиболее эффективным способ сделать это?

ответ

9

Вы можете присоединиться к таблице из подзапроса, который возвращает только уникальный foo, используя LEFT JOIN. Строки, которые не имеют матч на вложенный запрос будет удален, как вы хотели, например,

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 

Для повышения производительности, добавьте индекс столбца Foo.

ALTER TABLE tableName ADD INDEX(foo) 
+0

Это отлично работает, но это слишком медленно (у меня есть очень большой стол). –

+0

добавьте индекс в столбец, чтобы он работал быстрее, например, 'ALTER TABLE tableName ADD INDEX (foo)' и видеть производительность. –

+0

Спасибо, но я уже это сделал. Во всяком случае, это самый быстрый способ сделать это. –

8

Использование 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) 

Использование IN:

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

Если я прав, существующая версия, которую вы здесь написали, значительно быстрее, чем версия. Имея это в виду, есть ли аргумент для версии? – usumoio

Смежные вопросы