Ето моя опит да реша този проблем:
select y,
sum( hrs_per_week )
from tmp_ranges t
join(
select daterange( x,
lead(x) over (order by x) ) As y
from (
select lower( rng ) As x
from tmp_ranges
union
select upper( rng )
from tmp_ranges
order by x
) y
) y
on t.rng && y.y
group by y
order by y
Демонстрация:http://sqlfiddle.com/#!15/ef6cb/13
Най-вътрешната подзаявка събира всички гранични дати в един набор с помощта на union
, след което ги сортира.
След това външната подзаявка изгражда нови диапазони от съседни дати с помощта на lead
функция.
В крайна сметка тези нови диапазони се присъединяват към изходната таблица в главната заявка, агрегирани и sum
се изчислява.
РЕДАКТИРАНЕ
Поръчката order by
клаузата в най-вътрешната заявка е излишна и може да бъде пропусната, защото lead(x) over
caluse подрежда записите по дати и набор от резултати от най-вътрешната подзаявка не трябва да се сортира.