create table TimeSheets(
StartDate Date,
EndDate Date,
primary key (StartDate));
insert into TimeSheets values(to_date('20050101','yyyymmdd'),to_date('20050103','yyyymmdd'));
insert into TimeSheets values(to_date('20050102','yyyymmdd'),to_date('20050104','yyyymmdd'));
insert into TimeSheets values(to_date('20050104','yyyymmdd'),to_date('20050105','yyyymmdd'));
insert into TimeSheets values(to_date('20050106','yyyymmdd'),to_date('20050109','yyyymmdd'));
insert into TimeSheets values(to_date('20050109','yyyymmdd'),to_date('20050109','yyyymmdd'));
insert into TimeSheets values(to_date('20050112','yyyymmdd'),to_date('20050115','yyyymmdd'));
insert into TimeSheets values(to_date('20050113','yyyymmdd'),to_date('20050114','yyyymmdd'));
insert into TimeSheets values(to_date('20050114','yyyymmdd'),to_date('20050114','yyyymmdd'));
insert into TimeSheets values(to_date('20050117','yyyymmdd'),to_date('20050117','yyyymmdd'));
commit;
--■■■インラインビューを使う方法■■■
select StartDate,min(EndDate) as EndDate
from
(select a.StartDate,b.EndDate
from TimeSheets a,TimeSheets b
where a.EndDate <= b.EndDate
and not exists(select 1 from TimeSheets c
where (c.StartDate < a.StartDate and a.StartDate <= c.EndDate)
or (c.StartDate <= b.EndDate and b.EndDate < c.EndDate)))
group by StartDate
order by StartDate;
--■■■インラインビューを使わない方法■■■
select a.StartDate,min(b.EndDate) as EndDate
from TimeSheets a,TimeSheets b
where a.EndDate <= b.EndDate
and not exists(select 1 from TimeSheets c
where (c.StartDate < a.StartDate and a.StartDate <= c.EndDate)
or (c.StartDate <= b.EndDate and b.EndDate < c.EndDate))
group by a.StartDate
order by a.StartDate;
--■■■階層問い合わせを使う方法1(10g以降)■■■
select min(connect_by_root StartDate) as StartDate,EndDate
from TimeSheets
where connect_by_IsLeaf = 1
connect by nocycle prior EndDate between StartDate and EndDate
group by EndDate
order by StartDate;
--■■■階層問い合わせを使う方法2(10g以降)■■■
select connect_by_root StartDate as StartDate,EndDate
from TimeSheets a
where connect_by_IsLeaf = 1
start with not exists(select 1 from TimeSheets b
where a.RowID != b.RowID
and a.StartDate between b.StartDate and b.EndDate)
connect by nocycle prior EndDate between StartDate and EndDate
order by StartDate;
--■■■分析関数のrange指定を使う方法■■■
select min(StartDate) as StartDate,max(EndDate) as EndDate
from (select StartDate,EndDate,
sum(willSum) over(order by StartDate) as GID
from (select StartDate,EndDate,
case when StartDate
<= max(EndDate) over(order by StartDate
range between unbounded preceding
and 1 preceding)
then 0 else 1 end as willSum
from TimeSheets))
group by GID
order by StartDate;