Более того, сложная задача, так как вы не можете доверять какому-либо порядку интервалов. Я атакую его, удаляя подинтервалы (интервалы, полностью покрытые другим интервалом). После этого я могу следовать порядку, определенному START_DATE, чтобы увидеть, перекрывается ли предыдущий интервал со следующим, и применить стандартный механизм группировки.
with subs as (
/* first remove all intervals that are subsets of other intervals */
select * from tst t1
where NOT exists (select null from tst t2 where t2.start_date < t1.start_date and t1.end_date < t2.end_date)
),overlap as (
select APPLN_NO, START_DATE, END_DATE,
case when (nvl(lag(END_DATE) over (partition by APPLN_NO order by START_DATE),START_DATE-1) < START_DATE) then
row_number() over (partition by APPLN_NO order by START_DATE) end grp
from subs),
overlap2 as (
select
APPLN_NO, START_DATE, END_DATE, GRP,
last_value(grp ignore nulls) over (partition by APPLN_NO order by START_DATE) as grp2
from overlap)
select
APPLN_NO, min(START_DATE) START_DATE, max(END_DATE) END_DATE
from overlap2
group by APPLN_NO, grp2
order by 1,2
;
Для проверки запроса здесь моя настройка
drop table tst ;
create table tst
(appln_no number,
start_date date,
end_date date);
insert into tst values (1001009, to_date('01-10-15','dd-mm-rr'),to_date('06-10-15','dd-mm-rr'));
insert into tst values (1001009, to_date('02-10-15','dd-mm-rr'),to_date('04-10-15','dd-mm-rr'));
insert into tst values (1001009, to_date('03-10-15','dd-mm-rr'),to_date('04-10-15','dd-mm-rr'));
insert into tst values (1001009, to_date('03-10-15','dd-mm-rr'),to_date('05-10-15','dd-mm-rr'));
insert into tst values (1001009, to_date('04-10-15','dd-mm-rr'),to_date('07-10-15','dd-mm-rr'));
insert into tst values (1001009, to_date('09-10-15','dd-mm-rr'),to_date('10-10-15','dd-mm-rr'));
insert into tst values (1001009, to_date('12-10-15','dd-mm-rr'),to_date('16-10-15','dd-mm-rr'));
insert into tst values (1001009, to_date('13-10-15','dd-mm-rr'),to_date('14-10-15','dd-mm-rr')); /* this is added to make it more interesting */
insert into tst values (1001009, to_date('15-10-15','dd-mm-rr'),to_date('17-10-15','dd-mm-rr'));
дайте
APPLN_NO START_DATE END_DATE
---------- ------------------- -------------------
1001009 01.10.2015 00:00:00 07.10.2015 00:00:00
1001009 09.10.2015 00:00:00 10.10.2015 00:00:00
1001009 12.10.2015 00:00:00 17.10.2015 00:00:00
как и ожидалось.
person
Marmite Bomber
schedule
21.10.2015