从数据表中删除所有重复行的最有效方法是什么?

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 |

什么是最高效的方法来完成这个任务?
2个回答

9
您可以使用LEFT JOIN从返回仅包含唯一foo的子查询中加入表格。未在子查询中匹配的行将被删除,如下所示:
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)

这个功能很完美,但速度太慢了(我有一个非常大的表格)。 - Andrew Shulgin
在列上添加索引,这样它的性能会更快,例如:ALTER TABLE tableName ADD INDEX(foo),然后查看性能。 - John Woo
谢谢,但我已经做过了。不过这确实是最快的方法,无论如何,我明白了。 - Andrew Shulgin

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)

如果我没错的话,你在这里编写的 exists 版本比 in 版本快得多。考虑到这一点,是否有任何理由使用 in 版本? - usumoio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接