sql >> Base de Datos >  >> RDS >> Oracle

Oracle sqlRestar entre dos fechas

Supongo que esto es tarea, así que algunos consejos...

Primero, nunca almacene fechas como varchar , les causará a usted y al optimizador todo tipo de problemas.

En segundo lugar, la date de Oracle El tipo de datos solo se puede almacenar con una precisión de segundo, y su cadena tiene fracciones de segundo, por lo que está mirando timestamp en lugar de date . Puede convertir su cadena en una marca de tiempo con to_timestamp() función, pasando una máscara de formato adecuada . Oh, está bien, me siento generoso:

select to_timestamp(start_date, 'DD-Mon-RR HH.MI.SS.FF9 AM') from your_table;

Tercero, restar dos marcas de tiempo le dará un interval tipo de datos, de los cuales deberá extraer la información que desea en un formato legible. Busque en este sitio o en otro lugar para la resta de marca de tiempo, pero lo señalaré en este reciente como muestra.

El promedio es un poco más complicado, por lo que es posible que desee convertir sus intervalos en números para eso; vuelva a buscar preguntas anteriores, como esta . El tamaño de los intervalos, la precisión que realmente le interesa y la forma en que desea que se formatee la salida, etc. influirán en el enfoque que desea adoptar.

Si necesita un resultado aproximado, la respuesta de @Joachim Isaksson le dará eso:'aproximado' debido al redondeo; una duración de menos de un segundo se mostrará como cero, por ejemplo. El mismo efecto se puede ver con las marcas de tiempo emitidas a fechas, que también pierden las fracciones de segundo:

select 24*60*60*avg(
    cast(to_timestamp(step_ending_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as date)
        - cast(to_timestamp(step_starting_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as date)
    ) as avg_duration
from process_audit;

Se puede encontrar una respuesta más precisa extrayendo los diversos componentes de las marcas de tiempo, como en una pregunta a la que me vinculé anteriormente. Es posible que no los necesite todos si sabe que sus duraciones son siempre inferiores a una hora, por ejemplo, pero si necesita más de uno (es decir, si una duración podría ser más de un minuto), entonces usar una expresión de tabla común intermedia simplifica las cosas a poco:

with cte as (
    select to_timestamp(step_ending_time, 'DD-Mon-RR HH.MI.SS.FF9 AM')
        - to_timestamp(step_starting_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as duration
    from process_audit
)
select avg(extract(second from duration)
    + extract(minute from duration) * 60
    + extract(hour from duration) * 60 * 60
    + extract(day from duration) * 60 * 60 * 24) as avg_duration
from cte;

Con dos filas de muestra, una con un intervalo de exactamente un segundo y otra con exactamente 1,5 segundos, esto da el resultado 1.25 .