SQL新手在这里。我有一个破碎的打卡/打出类型表,其中有数百万条记录由传统的坏应用程序提供,该应用程序在快速插入另一个重复记录之前未检查先前的登录/注销。该应用程序已修复,但我需要清理该表以保留历史数据,以便将其提供给将来的报告。
简而言之,我试图保留每个最小登录行,然后是下一个最小注销行,并丢弃其他所有内容。糟糕的应用程序允许重复登录和注销... grrrr。
每个"重复的行"我在这里搜索的类型问题似乎并不适用于这种类型的分组情况。从很长一段时间的潜伏者我知道你们想看看我已经尝试过但已经尝试了几十次愚蠢的查询尝试并没有结束。任何指导都将不胜感激。
这是表格以及我尝试使用架构and the fiddle做什么
+---------------------+-------+-------------+---------------+
| 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
+---------------------+-------+-------------+---------------+
答案 0 :(得分:1)
我会使用auto_increment列创建表的副本。这样,您可以更轻松,更有效地比较两个邻居行。
在新表中查找与前一行具有相同agent
和etype
的行,并使用DELETE语句中的唯一列将结果与原始表连接。
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;
演示:http://sqlfiddle.com/#!9/3e96b/2
但是,您应首先在uniqueid
上建立一个索引。
答案 1 :(得分:0)
你走了:
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;