使用sql删除重复的行

时间:2011-12-19 20:18:29

标签: mysql sql delete-row

我试图从我的mysql表中删除重复的行。我尝试了多个查询,但我一直在收到此错误:#1093 - 您无法在FROM子句中为更新指定目标表'usa_city'

表格如下:

usa_city
--------
id(pk)
id_state
city_name

我厌倦的疑问是:

DELETE FROM usa_city
WHERE id NOT IN
(
SELECT MIN(id)
FROM usa_city
GROUP BY city_name, id_state
)

DELETE
FROM usa_city
WHERE usa_city.id IN

-- List 1 - all rows that have duplicates
(SELECT F.id
FROM usa_city AS F
WHERE Exists (SELECT city_name, id_state, Count(id)
FROM usa_city
WHERE usa_city.city_name = F.city_name
   AND usa_city.id_state = F.id_state
GROUP BY usa_city.city_name, usa_city.id_state
HAVING Count(usa_city.id) > 1))
AND usa_city.id NOT IN

-- List 2 - one row from each set of duplicate
(SELECT Min(id)
FROM usa_city AS F
WHERE Exists (SELECT city_name, id_state, Count(id)
FROM usa_city
WHERE usa_city.city_name = F.city_name
   AND usa_city.id_state = F.id_state
GROUP BY usa_city.city_name, usa_city.id_state
HAVING Count(usa_city.id) > 1)
GROUP BY city_name, id_state);

提前致谢。

5 个答案:

答案 0 :(得分:4)

首先尝试选择重复项,然后删除它们

DELETE FROM usa_city WHERE city_id IN
(
SELECT city_id FROM usa_city
GROUP BY city_name, id_state
HAVING count(city_id) > 1
)

希望它有所帮助!!!

修改:根据评论如果您想保留一条记录,您可以进行加入并保持最低值

DELETE c1 FROM usa_city c1, usa_city c2 WHERE c1.id < c2.id AND 
(c1.city_name= c2.city_name AND c1.id_state = c2.id_state)

请务必在执行上述查询之前进行备份......

答案 1 :(得分:2)

来自mysql documentation

  

&#34;目前,您无法从表中删除并从中进行选择   子查询中的表。&#34;

但是here是更新的解决方法,也适用于删除。

另外,你可以选择行,然后在php中例如在循环中删除它们

答案 2 :(得分:0)

您可以在此处找到问题的答案:How to delete duplicate records in mysql database?

您应该使用关键字段来改善数据库以防止重复行,因此您不需要在将来清除。

答案 3 :(得分:0)

编辑:如果您按照BloodyWorld发布的链接找到此解决方案,那么如果它有效,请继续向上投票DMin的帖子here

发现这个浏览互联网(#1 google结果为mysql删除重复的行),你试过吗?

delete from table1
USING table1, table1 as vtable
WHERE (NOT table1.ID=vtable.ID)
AND (table1.field_name=vtable.field_name)

答案 4 :(得分:0)

从您的示例来看,当您说“重复”时,您的意思是“拥有id_statecity_name的相同组合”,对吗?如果删除了重复项后,我强烈建议在{id_state, city_name}上创建一个UNIQUE约束。

要实际删除重复项,仅仅识别重复项集是不够的,还必须确定哪些标识的重复项保留。假设您要保留具有最小id的那些,以下SQL将完成这项工作:

CREATE TEMPORARY TABLE usa_city_to_delete AS
    SELECT id FROM usa_city T1
    WHERE EXISTS (
        SELECT * FROM usa_city T2
        WHERE
            T1.id_state = T2.id_state 
            AND T1.city_name = T2.city_name
            AND T1.id > T2.id
    );

DELETE FROM usa_city
WHERE id IN (SELECT id FROM usa_city_to_delete);

DROP TEMPORARY TABLE usa_city_to_delete;

不幸的是,MySQL不允许DELETE中的相关子查询,否则我们可以在单个语句中完成,而不使用临时表。

---编辑---

您不能拥有相关的子查询,但可以使用JOIN,如Carlos Quijano answer所示。此外,根据Kokers的建议,可以隐式创建临时表

所以它 可以在一个语句中完成,与我上面写的相反......