Fondamentalement, pour résoudre ce problème, vous avez juste besoin d'une liste de nombres.
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;
Cela fonctionne jusqu'à 100 heures de différence dans les dates. Vous pouvez ajuster le 100
pour vos besoins. Vous pouvez même utiliser une sous-requête pour obtenir la bonne valeur maximale.
Il existe quelques astuces qui peuvent simplifier la logique. Je pense que la logique ci-dessus est la plus claire. Il parcourt les heures. Si l'heure comparée est la première heure, utilisez 60 - minutes. Si c'est le dernier, utilisez les minutes. Sinon, utilisez 60.