I grund och botten, för att lösa detta behöver du bara en lista med siffror.
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;
Detta fungerar för upp till 100 timmars skillnad mellan datumen. Du kan justera 100
för dina behov. Du kan till och med använda en underfråga för att få rätt maxvärde.
Det finns några knep som kan förenkla logiken. Jag tror att ovanstående logik är tydligast. Den cyklar genom timmarna. Om den jämförda timmen är den första timmen, använd 60 - minuter. Om den sista, använd minuterna. Annars använder du 60.