【问题标题】:finding duplicate rows on more than one field在多个字段上查找重复行
【发布时间】:2011-09-30 16:50:28
【问题描述】:

我正在使用此查询根据两个字段查找重复项:

SELECT 
    last_name, 
    first_name,
    middle_initial,
    COUNT(last_name) AS Duplicates,
    IF(rec_id = '', 1, 0) AS has_REC_ID 
FROM files
GROUP BY last_name, first_name
HAVING COUNT(last_name) > 1 AND COUNT(first_name) > 1;

好的,这将返回一组包含名字、姓氏和中间名的行,一个名为“Duplicates”的列包含很多 2,以及一个名为 has_REC_ID 的列包含混合的 1 和 0。

最终,我要做的是找到哪些行匹配名字和姓氏 - 然后对于每一对,找到具有 ('') 作为 rec_id 值的行,分配从具有 rec_id 的记录中获取 rec_id 值,然后删除首先具有 rec_id 的记录。

所以对于初学者来说,我会创建一个新列并执行以下操作:

UPDATE files a 
SET a.has_dup    --new column
    = if(a.last_name IN (
                         SELECT b.last_name
                         FROM files b
                         GROUP BY b.last_name 
                         HAVING COUNT(b.last_name) > 1
                        )
      , 1, null);

但是 MySQL 返回:“You can't specify target table 'a' for update in from 子句”

我敢打赌,没有什么比我在这里尝试的方法更荒谬了。有人可以帮我弄清楚那是什么吗?

更新:我也试过了:

UPDATE files a 
SET a.has_dup = 1
WHERE a.last_name IN (
                         SELECT b.last_name
                         FROM files b
                         GROUP BY b.last_name 
                         HAVING COUNT(b.last_name) > 1
                     );

...并得到相同的错误消息。

【问题讨论】:

    标签: mysql duplicates


    【解决方案1】:

    你可以:

    1) 创建一个保持表

    2) 用名字和姓氏匹配且 rec_id != ""

    的行填充持有表

    3) 从原始表(文件)中删除名字和姓氏匹配且 rec_id != ""

    的行

    4) 更新原始表中名字和姓氏匹配且 rec_id = "" 的行。

    5) 删除保留表

    比如:

    create table temp
    (
    firstname varchar(100) not null,
    lastname varchar(100) not null,
    rec_id int not null
    );
    
    
    insert into temp (select firstname,lastname,rec_id from files where firstname =    lastname and rec_id != '');
    
    
    delete from files where firstname = lastname and rec_id != '';
    
    update files f
    set f.rec_id = (select t.rec_id from temp t where f.firstname = t.firstname and f.lastname = t.lastname)
    where f.firstname = f.lastname 
    and f.rec_id != '';
    
    
    drop table temp;
    

    【讨论】:

    • 是的,这些方面的内容应该很有帮助。谢谢!
    【解决方案2】:

    来自the documentation

    目前,您无法在子查询中更新表并从同一个表中进行选择。

    我想不出一个快速的解决方法。


    更新

    显然,there is a "quick" workaround,但它的性能是否是另一个问题。这就是通过引入一个临时表来添加一个新的间接层:

    UPDATE files a 
    SET a.has_dup    --new column
        = if(a.last_name IN (
                         SELECT b.last_name
                         FROM
                              (SELECT * FROM files)      -- new table target
                         b
                         GROUP BY b.last_name 
                         HAVING COUNT(b.last_name) > 1
                        ),
          1, null);
    

    【讨论】:

    • 这可以解释。但是,一个快速的解决方法可能是选择另一个名为其他表的表,对吗?
    • @tjb1982:对于初学者来说,不涉及将所有数据复制到第二个重复表中。 :)
    【解决方案3】:

    我没有要测试的 MySQL,但我认为这应该可以工作:(EDITED->FAIL)

    UPDATE files
    SET has_dup
        = if(last_name IN (
                             SELECT b.last_name
                             FROM files b
                             GROUP BY b.last_name 
                             HAVING COUNT(b.last_name) > 1
                          )
          , 1, null);
    

    已编辑:再试一次:

    UPDATE files f, (SELECT b.last_name
                       FROM files b
                   GROUP BY b.last_name 
                     HAVING COUNT(b.last_name) > 1
                    ) as duplicates
       SET f.has_dup = 1
     WHERE f.last_name = duplicates.last_name
    

    【讨论】:

    • 不。谢谢,但现在消息是:“您无法在 from 子句中指定目标表 'files' 进行更新”
    • @tjb1982 抱歉,请检查第二个。 (我应该添加另一个解决方案还是编辑错误的解决方案?)
    • 我没有对此投反对票,但请参阅 Tomalak 的回答,认为这不是正确的做法:文档。
    • @tjb1982 似乎有解决方法:xaprb.com/blog/2006/06/23/…
    猜你喜欢
    • 2013-12-01
    • 1970-01-01
    • 2016-11-21
    • 1970-01-01
    • 2019-04-08
    • 2019-11-07
    • 2013-07-10
    • 2014-03-07
    • 2015-12-28
    相关资源
    最近更新 更多