架构:
create table Overlapping_Ranges (B date, E date);
insert into Overlapping_Ranges (B, E) values
(to_date('2013-03-10 10:00', 'yyyy-mm-dd hh24:mi'), to_date('2013-03-10 16:00', 'yyyy-mm-dd hh24:mi'));
insert into Overlapping_Ranges (B, E) values
(to_date('2013-03-10 15:00', 'yyyy-mm-dd hh24:mi'), to_date('2013-03-10 17:00', 'yyyy-mm-dd hh24:mi'));
insert into Overlapping_Ranges (B, E) values
(to_date('2013-03-10 20:00', 'yyyy-mm-dd hh24:mi'), to_date('2013-03-10 22:00', 'yyyy-mm-dd hh24:mi'));
create table Ranges_from_cursor (B date, E date);
insert into Ranges_from_cursor (B, E) values
(to_date('2013-03-10 12:00', 'yyyy-mm-dd hh24:mi'), to_date('2013-03-10 23:00', 'yyyy-mm-dd hh24:mi'));
选择:
select
to_char(c.B, 'yyyy-mm-dd hh24:mi') as "From",
to_char(c.E, 'yyyy-mm-dd hh24:mi') as "To",
sum(greatest(0, least(r.E, c.E) - greatest(r.B, c.B))) * 24 as "Hours Overlapped"
from
Ranges_from_cursor c,
(
select distinct
r.B, r.E
from
(
select
T as B,
lead(T) over (order by T) as E,
T + (lead(T) over (order by T) - T)/2 as M
from
(
select B as T from Overlapping_Ranges
union
select E as T from Overlapping_Ranges
)
) r
join Overlapping_Ranges o
on r.M between o.B and o.E
)r
group by c.B, c.E
order by 1
输出:
FROM TO HOURS OVERLAPPED
2013-03-10 12:00 2013-03-10 23:00 7
小提琴