совокупные диапазоны дат с пробелами в оракуле - PullRequest
1 голос
/ 07 марта 2019

Мне нужно агрегировать диапазоны дат, допускающие макс. 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 Ответ

3 голосов
/ 07 марта 2019

Если вы используете 12c, вы можете использовать одну из моих любимых функций SQL: сопоставление с образцом (match_recognize).

При этом вам нужно определить переменную шаблона. Здесь вы проверите, что дата начала текущей строки находится в пределах двух дней с даты окончания предыдущей строки. Который является:

startdate <= prev ( stopdate ) + 2

Шаблон, который вы ищете, - это любая строка, за которой следует ноль или более строк, соответствующих этому критерию.

Итак, у вас есть переменная "всегда истинно" strt, за которой следуют * (квантификатор с нулевым или более регулярным выражением) вхождений переменной inside2:

( 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  

Если вы хотите узнать больше об этом, вы можете найти несколько примеров match_recognize здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...