Basicamente, para resolver isso você só precisa de uma lista de números.
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;
Isso funciona para até 100 horas de diferença nas datas. Você pode ajustar o
100
para suas necessidades. Você pode até usar uma subconsulta para obter o valor máximo correto. Existem alguns truques que podem simplificar a lógica. Acho que a lógica acima é mais clara. Ele circula pelas horas. Se a hora comparada for a primeira hora, use 60 - minutos. Se for o último, use os minutos. Caso contrário, use 60.