create table my_data2(ID,staD,endD) as
select 108,date '2009-12-28',date '2010-01-22' from dual union all
select 108,date '2010-03-29',date '2010-04-11' from dual union all
select 108,date '2010-05-01',date '2010-05-31' from dual union all
select 111,date '2011-07-01',date '2011-07-16' from dual union all
select 222,date '2010-04-25',date '2010-05-02' from dual union all
select 222,date '2011-07-01',date '2011-07-16' from dual union all
select 222,date '2011-07-10',date '2011-07-20' from dual union all
select 333,date '2011-07-01',date '2011-07-10' from dual union all
select 333,date '2011-07-11',date '2011-07-15' from dual union all
select 333,date '2011-07-16',date '2011-07-30' from dual union all
select 444,date '2011-07-01',date '2011-07-10' from dual union all
select 444,date '2011-07-16',date '2011-07-30' from dual union all
select 445,date '2010-01-01',date '2010-04-30' from dual union all
select 445,date '2010-01-01',date '2010-05-31' from dual union all
select 445,date '2010-05-17',date '2010-08-06' from dual union all
select 658,date '2010-01-01',date '2010-04-30' from dual union all
select 658,date '2010-01-01',date '2010-05-31' from dual union all
select 658,date '2010-01-01',date '2010-05-31' from dual union all
select 777,date '2010-01-01',date '2010-01-10' from dual union all
select 777,date '2010-01-01',date '2010-01-16' from dual union all
select 777,date '2010-01-16',date '2010-01-17' from dual union all
select 777,date '2010-01-16',date '2010-01-20' from dual union all
select 777,date '2010-01-21',date '2010-01-30' from dual union all
select 999,date '2010-03-01',date '2010-03-14' from dual union all
select 999,date '2010-03-01',date '2010-04-24' from dual union all
select 999,date '2010-04-25',date '2010-05-02' from dual union all
select 1778,date '2010-01-04',date '2010-01-17' from dual union all
select 1778,date '2010-01-18',date '2010-01-31' from dual union all
select 1778,date '2010-02-01',date '2010-02-28' from dual union all
select 1778,date '2010-04-04',date '2010-05-02' from dual union all
select 1778,date '2010-05-03',date '2010-05-30' from dual union all
select 1778,date '2010-05-31',date '2010-06-27' from dual union all
select 1778,date '2010-07-19',date '2010-08-01' from dual union all
select 2535,date '2010-03-01',date '2010-03-14' from dual union all
select 2535,date '2010-03-15',date '2010-03-28' from dual union all
select 2535,date '2010-04-05',date '2010-05-02' from dual union all
select 2710,date '2010-05-01',date '2010-08-31' from dual union all
select 2710,date '2010-09-01',date '2010-12-31' from dual union all
select 2710,date '2011-01-01',date '2011-04-30' from dual union all
select 2710,date '2011-05-01',date '2011-08-31' from dual;
--■■■分析関数を使う方法■■■
select ID,staD,endD
from (select ID,min(staD) as staD,
max(endD) as endD,
Row_Number() over(partition by ID order by
case when sysdate between min(staD)
and max(endD)
then 1 -- 1st return the current summary range
when min(staD) > sysdate
then 2 -- 2nd return the min future summary range
else 3 end, -- 3rd return the max past summary range
case when min(staD) > sysdate
then GID else -GID end) as rn
from (select ID,staD,endD,
sum(willSum) over(partition by ID
order by staD) as GID
from (select ID,staD,
max(endD) as endD,
case when staD-1
<= max(max(endD))
over(partition by ID
order by staD
range between unbounded preceding
and 1 preceding)
then 0 else 1 end as willSum
from my_data2
group by ID,staD))
group by ID,GID)
where rn = 1;
--■■■階層問い合わせを使う方法(10g以降)■■■
select ID,staD,endD
from (select ID,staD,endD,
Row_Number() over(partition by ID
order by case when sysdate between staD
and endD
then 1 -- 1st return the current summary range
when staD > sysdate
then 2 -- 2nd return the min future summary range
else 3 end, -- 3rd return the max past summary range
case when staD > sysdate
then to_number(to_char(staD,'yyyymmdd'))
else -to_number(to_char(staD,'yyyymmdd')) end) as rn
from (select ID,min(connect_by_root staD) as staD,endD
from my_data2
where connect_by_IsLeaf = 1
connect by nocycle prior ID=ID
and prior endD+1 between staD and endD
group by ID,endD))
where rn = 1;