Vous devez séparer le décalage horaire en ses éléments constitutifs jour, heure, minute et seconde, combiner le nombre de jours * 24 avec le nombre d'heures et le recoller.
Lorsque vous soustrayez des dates, vous obtenez la différence en nombre de jours, vous devez donc convertir la partie fractionnaire en autres éléments, ce que vous pouvez faire avec une combinaison de trunc et mod; en utilisant un CTE pour rendre cela un peu plus facile à suivre et en montrant chaque valeur seule ainsi que combinée en une seule chaîne :
with y as (
select id, end_time - start_time as runtime
from mytable
)
select id,
runtime,
trunc(runtime) as days,
24 * trunc(runtime) as day_hours,
trunc(24 * mod(runtime, 1)) as hours,
trunc(60 * mod(24 * (runtime), 1)) as minutes,
trunc(60 * mod(24 * 60 * (runtime), 1)) as seconds,
lpad(24 * trunc(runtime)
+ trunc(24 * mod(runtime, 1)), 2, '0')
||':'|| lpad(trunc(60 * mod(24 * (runtime), 1)), 2, '0')
||':'|| lpad(trunc(60 * mod(24 * 60 * (runtime), 1)), 2, '0')
as runtime
from y;
ID RUNTIME DAYS DAY_HOURS HOURS MINUTES SECONDS RUNTIME
---------- ---------- ---------- ---------- ---------- ---------- ---------- --------
1 .184918981 0 0 4 26 16 04:26:16
2 1.14465278 1 24 3 28 18 27:28:18
Vous pouvez également convertir les dates en horodatages pour le calcul, ce qui vous donne un type d'intervalle, puis utiliser le extract
fonction pour obtenir les éléments à la place ; le principe est le même :
with y as (
select id,
cast(end_time as timestamp) - cast (start_time as timestamp) as runtime
from mytable
)
select id,
runtime,
extract (day from runtime) as days,
24 * extract (day from runtime) as day_hours,
extract (hour from runtime) as hours,
extract (minute from runtime) as minutes,
extract (second from runtime) as seconds,
lpad(24 * extract (day from runtime) + extract (hour from runtime), 2, '0')
||':'|| lpad(extract (minute from runtime), 2, '0')
||':'|| lpad(extract (second from runtime), 2, '0')
as runtime
from y;
ID RUNTIME DAYS DAY_HOURS HOURS MINUTES SECONDS RUNTIME
---------- ----------- ---------- ---------- ---------- ---------- ---------- --------
1 0 4:26:17.0 0 0 4 26 17 04:26:17
2 1 3:28:18.0 1 24 3 28 18 27:28:18
Ou une légère variation, en obtenant la différence des dates, puis en la convertissant en un intervalle :
with y as (
select id,
numtodsinterval(end_time - start_time, 'DAY') as runtime
from mytable
)
...
Démo SQL Fiddle.