mysql:删除重复特定值之间的行
这里是SQL新手。我有一个损坏的打孔输入/输出类型表,其中有数百万条记录,由一个遗留的坏应用程序提供,该应用程序在愉快地插入另一条重复记录之前没有检查以前的登录/注销。该应用程序是固定的,但我需要清理该表以保留历史数据,以便将其输入未来的报告中 简而言之,我试图保持每个最小登录行后面紧跟着下一个最小注销行,并放弃这两行之间的所有其他内容。坏应用允许重复登录和注销。。。grrrr 我在这里搜索的每一个重复的行类型问题似乎都不适用于这种分组情况。我知道你们很想看看我已经尝试过的东西,但是已经尝试了几十次愚蠢的查询尝试,但都没有成功。任何指导都将不胜感激 这是表以及我试图用schema做的事情mysql:删除重复特定值之间的行,mysql,Mysql,这里是SQL新手。我有一个损坏的打孔输入/输出类型表,其中有数百万条记录,由一个遗留的坏应用程序提供,该应用程序在愉快地插入另一条重复记录之前没有检查以前的登录/注销。该应用程序是固定的,但我需要清理该表以保留历史数据,以便将其输入未来的报告中 简而言之,我试图保持每个最小登录行后面紧跟着下一个最小注销行,并放弃这两行之间的所有其他内容。坏应用允许重复登录和注销。。。grrrr 我在这里搜索的每一个重复的行类型问题似乎都不适用于这种分组情况。我知道你们很想看看我已经尝试过的东西,但是已经尝试了几
+---------------------+-------+-------------+---------------+
| calldate | agent | etype | uniqueid |
+---------------------+-------+-------------+---------------+
| 2018-02-02 19:26:47 | 501 | agentlogin | 1517599607.71 |
| 2018-02-02 19:26:55 | 501 | agentlogin | 1517599615.72 |<-- delete
| 2018-02-02 19:27:32 | 501 | agentlogoff | 1517599652.73 |
| 2018-02-02 19:27:43 | 501 | agentlogin | 1517599663.74 |
| 2018-02-02 19:28:24 | 501 | agentlogoff | 1517599704.75 |
| 2018-02-02 19:29:02 | 501 | agentlogoff | 1517599742.76 |<-- delete
| 2018-02-02 19:29:39 | 501 | agentlogoff | 1517599778.77 |<-- delete
| 2018-02-02 19:34:54 | 501 | agentlogin | 1517600094.80 |
| 2018-02-02 19:35:23 | 501 | agentlogin | 1517600122.81 |<-- delete
| 2018-02-02 19:35:49 | 501 | agentlogin | 1517600149.82 |<-- delete
| 2018-02-02 19:36:04 | 501 | agentlogoff | 1517600164.83 |
| 2018-02-02 19:36:08 | 501 | agentlogoff | 1517600168.84 |<-- delete
+---------------------+-------+-------------+---------------+
给你:
select calldate,agent,etype,uniqueid
from test as t1
where not exists
(select *
from
test as t2
where t2.agent=t1.agent
and t2.etype=t1.etype
and t2.uniqueid<t1.uniqueid
and t2.uniqueid>ifnull((select max(uniqueid )
from test t3
where t3.agent=t1.agent
and t3.etype<>t1.etype
and t3.uniqueid<t1.uniqueid),0)
)
order by uniqueid;
我将创建一个带有自动增量列的表副本。这样,您可以更轻松、更有效地比较两个相邻行 在新表中查找与前一行具有相同代理和词组的行,并使用DELETE语句中的unique列将结果与原始表联接
create table tmp (
`id` int unsigned auto_increment primary key,
`calldate` datetime,
`uniqueid` varchar(32),
`agent` varchar(80),
`etype` varchar(80)
) as
select null as id, calldate, uniqueid, agent, etype
from test
order by agent, calldate, uniqueid
;
delete t
from tmp t1
join tmp t2
on t2.id = t1.id + 1
and t2.agent = t1.agent
and t2.etype = t1.etype
join test t on t.uniqueid = t2.uniqueid;
drop table tmp;
演示:
但是,您应该首先在uniqueid上有一个索引。表有多大?有主键吗?这和上一个没有太大区别,是吗?@Paul Spiegel-生产表有数百万行和其他不相关的数据和列。为了清楚起见,我只将相关的行/列转储到我的fiddle测试表中,而没有转储主键id列。但是uniqueid列是100%唯一的。@草莓-不,不是,但是,我想问一个新问题,因为原始问题与所用秒数的和/差有关,正如walter指出的,处理这种情况的最佳方法是修复表。我尝试了他的示例的许多变体,但由于登录/注销两侧的重复记录问题,这些变体无法正常工作。非常感谢。我不敢相信你这么快就想出了答案。也许有一天我可以把我的脑袋绕在SQL上,但我只是一个卑微的交易高手。非常感谢。很高兴能帮忙!你的JSFIDLE很有用!我最初将Obie的答案标记为正确,但从技术上讲,您的答案是正确的,因为Obie的解决方案会提取好的行,而您的解决方案会识别要删除的行。我很感谢你的帮助。谢谢你弄明白了。