汇总日期范围与Oracle中的差距

时间:2019-03-07 11:53:01

标签: oracle date range aggregate

我需要汇总日期范围,以便每个ID之间最多可以有2天的间隔。任何帮助将不胜感激

create table tt ( id int, startdate date, stopdate date);  
Insert into TT values (1,'24/05/2010', '29/05/2010');
Insert into TT values (1,'30/05/2010', '22/06/2010');
Insert into TT values (10,'26/06/2012', '28/06/2012');
Insert into TT values (10,'29/06/2012', '30/06/2012');
Insert into TT values (10,'01/07/2012', '30/07/2012');
Insert into TT values (10,'03/08/2012', '30/12/2012');
insert into TT values (90,'08/03/2002', '16/03/2002');
insert into TT values (90,'31/01/2002', '15/02/2002');
insert into TT values (90,'15/02/2002', '28/02/2002');
insert into TT values (90,'31/01/2002', '15/02/2004');
insert into TT values (90,'15/02/2004', '15/04/2004');
insert into TT values (90,'01/03/2002', '07/03/2002');

预期输出为:

1     24/05/2010    22/06/2010
10    26/06/2012    30/07/2012
10    03/08/2012    30/12/2012 
90    31/01/2002    15/04/2004

1 个答案:

答案 0 :(得分:3)

如果您使用的是12c,则可以使用我最喜欢的SQL功能之一:模式匹配(match_recognize)。

为此,您需要定义一个模式变量。您可以在此处检查当前行的开始日期是否在上一行的停止日期的两天内。就是

startdate <= prev ( stopdate ) + 2

您要搜索的模式是任何行,然后是零个或多个符合此标准的行。

因此,您有一个“始终为真”的strt变量,其后是*(正则表达式零个或多个量词)出现在inner2变量中:

( strt within2* ) 

我猜您还需要按ID划分范围。因此,我为此添加了一个分区。

将所有内容放在一起,您将得到:

select * 
from   tt match_recognize (
  partition by id
  order by startdate, stopdate
  measures
    first ( startdate ) startdate, 
    last ( stopdate ) stopdate
  pattern ( strt within2* ) 
  define 
    within2 as startdate <= prev ( stopdate ) + 2
);

ID   STARTDATE    STOPDATE     
   1 24/05/2010   22/06/2010   
  10 26/06/2012   30/07/2012   
  10 03/08/2012   30/12/2012  

如果您想进一步了解这一点,可以找到several match_recognize examples here