Fondamentalmente, per risolvere questo è sufficiente un elenco di numeri.
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;
Funziona fino a 100 ore di differenza tra le date. Puoi modificare il 100
per le tue esigenze. Puoi persino utilizzare una sottoquery per ottenere il valore massimo corretto.
Ci sono alcuni trucchi che possono semplificare la logica. Penso che la logica di cui sopra sia più chiara. Scorre le ore. Se l'ora confrontata è la prima ora, utilizzare 60 minuti. Se l'ultimo, usa i minuti. Altrimenti, usa 60.