Debe separar la diferencia horaria en sus elementos constituyentes de día, hora, minuto y segundo, combinar la cantidad de días * 24 con la cantidad de horas y volver a unirlos.
Al restar fechas, obtienes la diferencia como el número de días, por lo que debes convertir la parte fraccionaria en los otros elementos, lo que puedes hacer con una combinación de trunc y mod; usando un CTE para hacer que esto sea un poco más fácil de seguir y mostrando cada valor por sí solo y combinado en una sola cadena:
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
También puede convertir las fechas en marcas de tiempo para el cálculo, lo que le da un tipo de intervalo, y luego usar el extract
función para obtener los elementos en su lugar; aunque el director es el mismo:
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
O una ligera variación, obteniendo la diferencia de las fechas y luego convirtiéndola en un intervalo:
with y as (
select id,
numtodsinterval(end_time - start_time, 'DAY') as runtime
from mytable
)
...
Demostración de SQL Fiddle.