【问题标题】:Remove duplicates using only a MySQL query?仅使用 MySQL 查询删除重复项?
【发布时间】:2011-03-23 23:18:08
【问题描述】:

我有一个包含以下列的表格:

URL_ID    
URL_ADDR    
URL_Time

我想使用 MySQL 查询删除 URL_ADDR 列上的重复项。

有没有可能在不使用任何编程的情况下做这样的事情?

【问题讨论】:

  • SQL 正在编程...
  • URL_ADDR 中的 URL 长什么样?它们都具有相同的格式吗?即:有或没有www。

标签: sql mysql


【解决方案1】:

您可以按 URL_ADDR 进行分组,这将有效地为您在 URL_ADDR 字段中提供不同的值。

select 
 URL_ID
 URL_ADDR
 URL_Time
from
 some_table
group by
 URL_ADDR

享受吧!

【讨论】:

  • 这正是我想要的!
【解决方案2】:

这会将具有最高URL_ID 的那些留给特定的URL_ADDR

DELETE FROM table
WHERE URL_ID NOT IN 
    (SELECT ID FROM 
       (SELECT MAX(URL_ID) AS ID 
        FROM table 
        WHERE URL_ID IS NOT NULL
        GROUP BY URL_ADDR ) X)   /*Sounds like you would need to GROUP BY a 
                                   calculated form - e.g. using REPLACE to 
                                  strip out www see Daniel's answer*/

(派生表'X'是avoid the error"你不能在FROM子句中指定目标表'tablename'进行更新")

【讨论】:

  • @Vilx:这就是你把它埋在另一个子查询中的原因。
【解决方案3】:

嗯,你总是可以:

  1. 创建一个临时表;
  2. INSERT INTO ... SELECT DISTINCT从原表进入临时表;
  3. 清除原始表格
  4. INSERT INTO ... SELECT从临时表进入原表
  5. 删除临时表。

它笨拙且笨拙,并且需要多次查询(更不用说特权),但如果您找不到其他解决方案,它会解决问题。

【讨论】:

    【解决方案4】:

    您可能想尝试http://labs.creativecommons.org/2010/01/12/removing-duplicate-rows-in-mysql/中提到的方法。

    ALTER IGNORE TABLE your_table ADD UNIQUE INDEX `tmp_index` (URL_ADDR);
    

    【讨论】:

    【解决方案5】:

    考虑以下测试用例:

    CREATE TABLE mytb (url_id int, url_addr varchar(100));
    
    INSERT INTO mytb VALUES (1, 'www.google.com');
    INSERT INTO mytb VALUES (2, 'www.microsoft.com');
    INSERT INTO mytb VALUES (3, 'www.apple.com');
    INSERT INTO mytb VALUES (4, 'www.google.com');
    INSERT INTO mytb VALUES (5, 'www.cnn.com');
    INSERT INTO mytb VALUES (6, 'www.apple.com');
    

    我们的测试表现在包含的位置:

    SELECT * FROM mytb;
    +--------+-------------------+
    | url_id | url_addr          |
    +--------+-------------------+
    |      1 | www.google.com    |
    |      2 | www.microsoft.com |
    |      3 | www.apple.com     |
    |      4 | www.google.com    |
    |      5 | www.cnn.com       |
    |      6 | www.apple.com     |
    +--------+-------------------+
    5 rows in set (0.00 sec)
    

    那么我们可以使用多表DELETE语法如下:

    DELETE t2
    FROM   mytb t1
    JOIN   mytb t2 ON (t2.url_addr = t1.url_addr AND t2.url_id > t1.url_id);
    

    ...这将删除重复的条目,只留下基于url_id的第一个url:

    SELECT * FROM mytb;
    +--------+-------------------+
    | url_id | url_addr          |
    +--------+-------------------+
    |      1 | www.google.com    |
    |      2 | www.microsoft.com |
    |      3 | www.apple.com     |
    |      5 | www.cnn.com       |
    +--------+-------------------+
    3 rows in set (0.00 sec)
    

    更新 - 进一步了解上述新 cmets:

    如果重复 URL 的格式不同,您可能需要应用 REPLACE() 函数来删除 www.http:// 部分。例如:

    DELETE t2
    FROM   mytb t1
    JOIN   mytb t2 ON (REPLACE(t2.url_addr, 'www.', '') = 
                       REPLACE(t1.url_addr, 'www.', '') AND 
                       t2.url_id > t1.url_id);
    

    【讨论】:

    • 那么,JOIN 不会触发 1093 错误?诚然,JOIN 不是子查询,但自我引用才是真正的问题......
    • @OMG: 好像没有:)
    • @OMG Poines: RE 1093 错误,我还尝试了一个 UPDATE 使用自引用 JOIN 和另一个使用从同一个表中选择的子查询。 JOIN 测试成功,而子查询失败并出现 1093 错误。 DELETE 似乎也是如此。
    【解决方案6】:

    如果您的 URL_ID 列是唯一的,这将起作用。

    DELETE FROM url WHERE URL_ID IN (
    SELECT URL_ID
    FROM url a INNER JOIN (
        SELECT URL_ADDR, MAX(URL_ID) MaxURLId 
        FROM url
        GROUP BY URL_ADDR
        HAVING COUNT(*) > 1) b ON a.URL_ID <> b.MaxURLId AND a.URL_ADDR = b.URL_ADDR
    )
    

    【讨论】:

      【解决方案7】:

      Daniel Vassallo 如何处理多列?

      DELETE t2 FROM directory1 t1 JOIN directory1 t2 ON (t2.page = t1.page, t2.parentTopic = t1.parentTopic, t2.title = t1.title, t2.description = t1.description, t2.linktype = t1.linktype, t2.priority = t1.priority AND t2.linkID > t1.linkID);

      可能是这样的?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-23
        • 1970-01-01
        • 2021-07-16
        • 1970-01-01
        • 2013-10-09
        相关资源
        最近更新 更多