删除重复的MySQL行,但保留一行

时间:2017-10-19 20:07:59

标签: mysql

我知道这听起来像是一个重复的问题,但我已经阅读了一些似乎相关的其他内容,但仍然无法弄清楚我的陈述应该是什么。希望我的问题不会过早地作为副本关闭。

我有一个包含多个列的calls表,但我想使用3列来查找完全匹配的列:call_start_datecall_fromcall_to然后使用名为call_duration的列作为决定是否保留行的决定因素。只应保留call_duration中较长的时间。

此查询可用于查找重复项,但如何修改此查询以删除编号较低的call_duration结果?

select t.*
from calls t join
 (select call_start_date, call_from, call_to, count(*) as NumDuplicates
  from calls
  group by call_start_date, call_from, call_to
  having NumDuplicates > 1
 ) tsum
 on t.call_start_date = tsum.call_start_date and t.call_from = tsum.call_from and t.call_to = tsum.call_to;

这是我的数据库结构:

CREATE TABLE `calls` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`call_from` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
`call_to` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
`call_start_date` datetime NOT NULL,
`call_direction` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`user` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`queue_name` varchar(100) COLLATE utf8_unicode_ci DEFAULT '',
`call_duration` time DEFAULT NULL,
`call_result` varchar(100) COLLATE utf8_unicode_ci DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25001 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

这是重复的截图示例。我只想保留call_duration列中数字较大的那个: enter image description here

1 个答案:

答案 0 :(得分:2)

请考虑选择此项。然后只需在确认后将select *更改为delete A即可提供您要删除的记录。

以这种方式思考:您需要一组数据,其最大呼叫持续时间由3个字段分组。然后,在这3个字段上加入此集合,并将最大持续时间加回到基本集合,以使所有唯一呼叫加入其最大呼叫持续时间。任何与该最大持续时间不匹配的记录都将具有空连接;因此,那些是您要删除的。

SELECT * 
FROM CALLS A
LEFT JOIN (SELECT call_from, call_to, Call_start_date, max(Call_Duration) mCD, min(ID) MID
            FROM calls
            GROUP BY call_from, call_to, Call_start_date) B
 on A.Call_from = B.call_from
and A.Call_to = B.call_to
and A.Call_start_date = B.call_Start_date
and A.call_duration = B.MCD
and A.ID = B.MID
WHERE B.mcd is null

所以删除将是:UPDATED WORKING DEMO:

DELETE A
FROM CALLS A
LEFT JOIN (SELECT call_from, call_to, Call_start_date, max(Call_Duration) mCD, min(ID) mid
            FROM CALLS Z
            GROUP BY call_from, call_to, Call_start_date) B
 on A.Call_from = B.call_from
and A.Call_to = B.call_to
and A.Call_start_date = B.call_Start_date
and A.call_duration = B.MCD
and A.ID = B.MID
WHERE B.mcd is null;