【问题标题】:Remove duplicate rows, except one, ** where rows contain NULL values **删除重复的行,除了一个,** 其中行包含 NULL 值**
【发布时间】:2012-09-05 16:30:29
【问题描述】:

这个问题与其他涉及在 MySQL 中删除重复行的 SO 问题类似但不同。

如果一个或多个列包含 NULL 值,则参考问题(如下)中的选择解决方案会失败。我在下面的 sqlfiddle 中包含了模式以及两个选择的答案,以说明以前的解决方案在哪里不起作用。

源架构:

CREATE TABLE IF NOT EXISTS `deldup` (
  `or_id` int(11) NOT NULL AUTO_INCREMENT,
  `order_id` varchar(5) NOT NULL,
  `txt_value` varchar(20) NOT NULL,
  `date_of_revision` date NOT NULL,
  `status` int(3) DEFAULT NULL,
  PRIMARY KEY (`or_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=16 ;

INSERT INTO `deldup` (`or_id`, `order_id`, `txt_value`, `date_of_revision`, `status`) VALUES
(1, '10001', 'ABC', '2003-03-06', NULL),
(2, '10001', 'RFE', '2003-03-11', NULL),
(3, '10002', 'ASE', '2009-08-05', NULL),
(4, '10003', 'PEF', '2001-11-03', NULL),
(5, '10004', 'OIU', '1999-10-29', NULL),
(6, '10005', 'FOO', '2002-03-01', NULL),
(7, '10006', 'RTY', '2005-08-19', NULL),
(8, '10001', 'NND', '2003-03-20', NULL),
(9, '10005', 'VBN', '2002-02-19', NULL),
(10, '10002', 'AAQ', '2009-08-13', NULL),
(11, '10002', 'EEW', '2009-08-07', NULL),
(12, '10001', 'ABC', '2003-03-06', 3),
(13, '10001', 'ABC', '2003-03-06', 3),
(14, '10001', 'ABC', '2003-03-06', NULL),
(15, '10001', 'ABC', '2003-03-06', NULL);

解决方案示例 1:

http://sqlfiddle.com/#!2/983f3/1

create temporary table tmpTable (or_id int);

insert  tmpTable
        (or_id)
select  or_id
from    deldup yt
where   exists
        (
        select  *
        from    deldup yt2
        where   yt2.txt_value = yt.txt_value

                and yt2.order_id = yt.order_id
                and yt2.date_of_revision = yt.date_of_revision
                and yt2.status = yt.status
                and yt2.or_id > yt.or_id
        );

delete  
from    deldup
where   or_id in (select or_id from tmpTable);

请注意,包含非空行值的行已成功删除,但未删除包含空值的行(请参阅生成的 SELECT 查询中的第 14 行和第 15 行)。


解决方案示例 2:

http://sqlfiddle.com/#!2/8a4f8/1

DELETE 
    n1 
FROM 
    deldup n1, 
    deldup n2 
WHERE 
    n1.or_id                < n2.or_id AND 
    n1.order_id             = n2.order_id AND 
    n1.txt_value            = n2.txt_value AND 
    n1.date_of_revision     = n2.date_of_revision AND
    n1.status               = n2.status 

此解决方案涉及的代码更少,工作原理与示例 1 相同,包括排除包含空值的行。


如何删除其中一个列值包含 NULL 值的重复行?


参考资料:

Delete all Duplicate Rows except for One in MySQL?

Remove duplicate rows in MySQL

How to remove duplicate entries from a mysql db?

【问题讨论】:

    标签: mysql null duplicates


    【解决方案1】:

    this之类的东西简单地调整第二个解决方案怎么样:

    WHERE
      ...
      (n1.status IS NULL AND n2.status IS NULL 
       OR n1.status = n2.status)
    

    我假设您仅在所有值都重复时才认为该记录是重复的。

    【讨论】:

    • 其他字段不用检查,定义为NOT NULL
    • 啊,我刚才注意到了。我的实际数据库在其他列上设置了 NULL。感谢您的回复,已接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多