Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Oracle sqlSubtract entre duas datas


Imagino que seja dever de casa, então algumas dicas...

Primeiro, nunca armazene datas como varchar , isso causará a você e ao otimizador todos os tipos de problemas.

Segundo, a date da Oracle tipo de dados só pode armazenar com precisão de segundo, e sua string tem frações de segundo, então você está olhando para timestamp em vez de date . Você pode converter sua string em um carimbo de data/hora com o to_timestamp() função, passando uma máscara de formato adequada . Oh OK, estou me sentindo generoso:
select to_timestamp(start_date, 'DD-Mon-RR HH.MI.SS.FF9 AM') from your_table;

Terceiro, subtrair dois timestamps fornecerá um interval tipo de dados, do qual você precisará extrair as informações desejadas em um formato legível. Pesquise neste site ou em outro lugar para subtração de carimbo de data/hora, mas indicarei este recente como amostra.

A média é um pouco mais complicada, então você pode querer converter seus intervalos em números para isso; pesquise novamente por perguntas anteriores, como esta . O tamanho dos intervalos, a precisão com a qual você realmente se importa e a maneira como deseja que a saída seja formatada etc. terão alguma influência na abordagem que você deseja adotar.

Se você precisar de um resultado aproximado, a resposta de @Joachim Isaksson fornecerá isso - 'aproximado' por causa do arredondamento; uma duração inferior a um segundo aparecerá como zero, por exemplo. O mesmo efeito pode ser visto com timestamps lançados em datas, que também perdem os segundos fracionários:
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;

Uma resposta mais precisa pode ser encontrada extraindo os vários componentes dos timestamps, como em uma pergunta que vinculei anteriormente. Você pode não precisar de todos eles se souber que suas durações são sempre inferiores a uma hora, digamos, mas se você precisar de mais de um (ou seja, se uma duração puder ser superior a um minuto), usar uma expressão de tabela comum intermediária simplifica as coisas. pedaço:
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;

Com duas linhas de amostra, uma com um intervalo de exatamente um segundo e outra com exatamente 1,5 segundo, isso fornece o resultado 1.25 .