【问题标题】:How can I delete rows with a few identical values in MySQL?如何在 MySQL 中删除具有几个相同值的行?
【发布时间】:2015-02-20 13:20:39
【问题描述】:

我有一个包含大约 11 个字段(列)的表,我知道有多个重复条目,但它们只在几个字段中重复。我想要做的是,如果两行或多行具有相同的小写ProviderNameAddress,以及相同的StateID,那么我想删除那些额外的行,只留下一份副本。我有类似的东西,但我不知道如何完成它。

SET SQL_SAFE_UPDATEs=0;
DELETE FROM providers
WHERE LCASE(ProviderName), LCASE(Address), StateID;

更新:

SET SQL_SAFE_UPDATES=0;
DELETE p1.* 
FROM providers AS p1
JOIN providers AS p2 
ON LCASE(p1.ProviderName) = LCASE(p2.ProviderName)
AND LCASE(p1.Address) = LCASE(p2.Address)
AND p1.Zip = p2.Zip
AND p1.StateID = p2.StateID
AND p1.ProviderId > p2.ProviderId

【问题讨论】:

    标签: mysql


    【解决方案1】:

    此答案假定您有一个唯一的 id 字段,用于区分具有重复值的行。它将保留id 最低的行。

    DELETE p1.*
    FROM providers AS p1
    JOIN providers AS p2 
    ON LCASE(p1.ProviderName) = LCASE(p2.ProviderName)
    AND LCASE(p1.Address) = LCASE(p2.Address)
    AND p1.StateID = p2.StateID
    AND p1.id > p2.id
    

    请注意,如果您的表格使用不区分大小写的排序规则,则无需调用LCASE

    更有效的查询可能是:

    DELETE p1.*
    FROM providers AS p1
    JOIN (SELECT LCASE(ProviderName) AS Name, LCASE(Address) AS Addr, StateID, MIN(id) AS id
          FROM providers
          GROUP BY Name, Addr, StateID
          HAVING COUNT(*) > 1) AS p2
    ON LCASE(p1.ProviderName) = p2.Name
    AND LCASE(p1.Address) = p2.Addr
    AND p1.StateID = p2.StateID
    AND p1.id > p2.id
    

    叉积要小得多,因为我们首先将所有具有相同值的提供者分组。此外,HAVING 子句过滤掉所有非重复项。

    【讨论】:

    • 从你的经验来看,你不介意看看我的question吗?
    • 你能检查我更新的代码吗,实际上是你的,当我执行它时,我收到以下消息:Error Code: 1205. Lock wait timeout exceeded; try restarting transaction。我每个人都有唯一的ProviderId,当我选择使用您的代码时,请检查此屏幕截图:prntscr.com/67jer1
    • 你的桌子有多大?这个查询不是很容易被索引,所以如果表很大的话会很慢。
    • @Barmar 我的表中有大约 900 万个条目。
    • 如果您使用不区分大小写的排序规则,并且在您要比较的列上有一个复合索引,这会很有帮助。您不能为比较函数调用结果的查询编制索引。
    【解决方案2】:

    要离开具有最高 id 的条目:

    SET SQL_SAFE_UPDATES = 0;
    DELETE n1 FROM provider n1, provider n2 WHERE n1.id < n2.id AND   
    LCASE(n1.ProviderName) = LCASE(n2.ProviderName) and LCASE(n1.Address) =   
    LCASE(n2.Address)   
    and n1.StateId = n2.StateId
    

    【讨论】:

    • 这会留下 ID 最高的条目,而不是最低的。
    猜你喜欢
    • 2013-08-25
    • 1970-01-01
    • 2022-08-11
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 2022-12-16
    • 1970-01-01
    • 2021-07-13
    相关资源
    最近更新 更多