2017-10-19 134 views
1

我知道这听起来像一个重复的问题,但我读了一堆似乎相关的其他人,仍然不能完全弄清楚我的声明应该是什么。希望我的问题不会过早地作为重复被关闭。删除重复的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

请考虑您的选择。那么只需在确认后给出要删除的记录,然后将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; 
+0

谢谢,奇怪,似乎为选择工作,但是当我改变'SELECT *''要在查询DELETE',我得到一个错误: '你的SQL语法有错误;检查对应于您的MariaDB服务器版本的手册,以获得在'A LEFT JOIN(选择call_from,call_to,Call_start_date,max(Call_Duration)mCD'在第2行''处使用的正确语法'我正在运行MariaDB 10.2.9 –

+1

'删除'需要'删除A',以便引用包含所有记录的呼叫集(别名A)。工作演示应该有帮助 – xQbert

+0

这就是它...非常感谢! –

相关问题