この質問は、MySQLで重複する行を削除することを含む他のSOの質問と似ていますが、異なります。
参照されている質問(以下)で選択されたソリューションは、1つ以上の列にNULL値が含まれている場合に失敗します。以前のソリューションが機能していない場所を示すために、以下のsqlfiddleにスキーマと2つの選択された回答を含めています。
ソーススキーマ:
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);
null以外の行値を含む行は正常に削除されますが、null値を含む行は削除されないことに注意してください(結果の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
このソリューションは、コードが少なくて済み、null値を含む行の除外を含め、例1とまったく同じように機能します。
列値の1つにNULL値が含まれている重複行を削除するにはどうすればよいですか?
参照: