表结构及数据如下:
需求:
将记录按照时间顺序排列,每三条记录为一组,若第二条记录与第一条记录相差5分钟,则删除该记录,若第三条与第二条记录相差5分钟,则删除该记录,
第二组同理,遍历全表,按要求删除记录。
例如:
9:55:00,10:00:00,10:05:00三条记录为一组,后两条记录均满足条件,均删除。(注意:虽然10:10:00的记录与10:05:00的记录也相差5分钟,但不是同一组,不能删除)
处理sql如下:
with t as
(select time_,
del_time_2,
case
when label_ = 2 then
null
else
del_time_3
end as del_time_3
from (select time_,
label_,
case
when (to_date(time_2, ‘hh24:mi:ss’) –
to_date(time_, ‘hh24:mi:ss’)) * 24 * 60 = 5 then
time_2
else
null
end as del_time_2,
case
when (to_date(time_3, ‘hh24:mi:ss’) –
to_date(time_2, ‘hh24:mi:ss’)) * 24 * 60 = 5 then
time_3
else
null
end as del_time_3
from (select time_, time_2, time_3, mod(rn, 3) as label_
from (select time_,
lead(time_, 1) over(order by 1) as time_2,
lead(time_, 2) over(order by 1) as time_3,
rownum as rn
from temp_a
order by to_date(time_, ‘hh24:mi:ss’))
where time_ is not null)
where label_ > 0))
select distinct del_time
from t unpivot(del_time for del_flag in(del_time_2, del_time_3));
步骤:
1、涉及到每条记录与其后的记录的比较,故使用lead() over()函数,将数据按时间顺序排序后,将本记录、其后的第一条记录、其后的第二条记录分别置于同一行,并编号;
2、若time_2和time_相差5分钟,time_3和time_2相差5分钟,则保留这两个时间点,置为del_time_2,del_time_3;
3、每三条记录为一组,利用编号rn字段对3取余,则每组的编号均为1、2、0,其中为编号为0的记录是每组的最后一条记录,其后的第一、第二条记录是下一组的记录,对本组的统计无意义,即使满足条件也不应删除,因此将编号为0的记录全部过滤;每组中编号为2的记录,其后的第二条记录是下一组的第一条记录,在本组中也不做考虑,置为null;
4、表中余下记录即为对应的时间点,满足条件的应删除的时间del_time_2、del_time_3;将该两列合并为一列,并去重,得出最终结果;