oracle 时间连续性判断

本文介绍了如何通过SQL查询在指定日期范围内具有连续ID的记录,并详细解释了使用分组、排序和窗口函数实现这一目标的方法。通过示例代码演示了筛选出在2010年1月1日至2010年12月31日连续的用户ID,并获取到该时间段内的最大连续日期范围。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1:模拟一张表来查询日期范围的连续性

create table myrecords
(
      id         number,  
      start_date number,   --开始时间
      end_date   number   --结束时间
);
insert into myrecords values (1,20100101,20101231);
insert into myrecords values (1,20100101,20110231);
insert into myrecords values (1,20100202,20100303);
insert into myrecords values (2,20100101,20101001);
insert into myrecords values (2,20100501,20101231);
insert into myrecords values (3,20100101,20100301);
insert into myrecords values (3,20100201,20100506);
insert into myrecords values (3,20100401,20101231);
insert into myrecords values (4,20100101,20100501);
insert into myrecords values (4,20100601,20101231);
insert into myrecords values (4,20100601,20101231);

SQL> select * from myrecords order by id,start_date,end_date;
 
        ID START_DATE   END_DATE
---------- ---------- ----------
         1   20100101   20101231
         1   20100101   20110231
         1   20100202   20100303
         2   20100101   20101001
         2   20100501   20101231
         3   20100101   20100301
         3   20100201   20100506
         3   20100401   20101231
         4   20100101   20100501
         4   20100601   20101231

 

2:要求查出在20100101到20101231 这段时间内连续的用户id,也就是上面记录中的1 , 2 , 3 都是成功的,4 的日期中间断开了..

--sql 思想.. 根据id分组,日期排序,判断每一行的日期,与上一个日期是否是连续的,若不连续则置标志break为1,外层过滤掉break为1的

select id, min(start_date), max(end_date)
  from (select id,
               start_date,
               end_date,
               (case
                 when start_date > max(end_date + 1)
                  over(partition by id order by start_date,
                           end_date rows between unbounded preceding and 1
                           preceding) then
                  1
                 else
                  0
               end) break
          from myrecords
         where 20100101 between start_date and end_date
            or start_date between 20100101 and 20101231)
 where break = 0
 group by id
having 20100101 between min(start_date) and max(start_date) and 20101231 between min(end_date) and max(end_date);

        ID MIN(START_DATE) MAX(END_DATE)
---------- --------------- -------------
         1        20100101      20110231
         2        20100101      20101231
         3        20100101      20101231

从结果可以看出,满足题目要求的员工id,12,3; 同时查询出了 满足这段时间的最大的连续日期范围;

参考from : http://www.itpub.net/thread-1223937-3-285.html

转载于:https://www.cnblogs.com/jianggc/archive/2011/09/30/2196282.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值