Zasadniczo, aby rozwiązać ten problem, potrzebujesz tylko listy liczb.
with nums as (
select 0.0 as n from dual
union all
select n + 1
from nums
where n < 100
)
select trunc(t.startdate + n * 1/ 24, 'hh'),
sum((case when trunc(t.startdate + n * 1/24, 'hh') = trunc(t.startdate, 'hh')
then 60 - extract(minute from startdate)
else 0
end) +
(case when trunc(t.startdate + n * 1/24, 'hh') > trunc(t.startdate, 'hh') and
trunc(t.startdate + n * 1/24, 'hh') < trunc(t.enddate, 'hh')
then 60
else 0
end) +
(case when trunc(t.startdate + n * 1/24, 'hh') = trunc(t.enddate, 'hh')
then extract(minute from enddate)
else 0
end)
) as minutes
from table t join
nums n
where trunc(t.startdate + n * 1/24, 'hh') <= t.enddate;
Działa to do 100 godzin różnicy w datach. Możesz dostosować 100
dla twoich potrzeb. Możesz nawet użyć podzapytania, aby uzyskać właściwą maksymalną wartość.
Istnieje kilka sztuczek, które mogą uprościć logikę. Myślę, że powyższa logika jest najjaśniejsza. Cyklicznie przechodzi przez godziny. Jeśli porównywana godzina to pierwsza godzina, użyj 60 - minut. Jeśli ostatni, użyj minut. W przeciwnym razie użyj 60.