Oracle
 sql >> Database >  >> RDS >> Oracle

Oracle sqlSubtract tra due date

Presumo che siano compiti a casa, quindi alcuni suggerimenti...

Innanzitutto non memorizzare mai le date come varchar , causerà a te e all'ottimizzatore ogni tipo di problema.

In secondo luogo, la date di Oracle datatype può essere archiviato solo in seconda precisione e la tua stringa ha frazioni di secondo, quindi stai guardando timestamp anziché date . Puoi convertire la tua stringa in un timestamp con to_timestamp() funzione, passando una maschera di formato . Oh OK, mi sento generoso:

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

Terzo, la sottrazione di due timestamp ti darà un interval tipo di dati, da cui dovrai estrarre le informazioni che desideri in un formato leggibile. Cerca in questo sito o altrove la sottrazione del timestamp, ma ti indicherò questo recente come campione.

La media è un po' più complicata, quindi potresti voler convertire i tuoi intervalli in numeri per quello; cerca di nuovo le domande precedenti, come questa . La dimensione degli intervalli, la precisione a cui tieni effettivamente e il modo in cui desideri formattare l'output, ecc. Influiranno sull'approccio che desideri adottare.

Se hai bisogno di un risultato approssimativo, la risposta di @Joachim Isaksson ti darà che - "approssimativo" a causa dell'arrotondamento; una durata inferiore a un secondo apparirà come zero, ad esempio. Lo stesso effetto può essere visto con i timestamp trasmessi alle date, che perde anche i secondi frazionari:

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;

Una risposta più precisa può essere trovata estraendo i vari componenti dei timestamp, come in una domanda che ho collegato in precedenza. Potresti non averne bisogno tutti se sai che le tue durate sono sempre inferiori a un'ora, diciamo, ma se ne hai bisogno di più di una (cioè se una durata potrebbe essere più di un minuto), l'uso di un'espressione di tabella comune intermedia semplifica le cose a bit:

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 due righe di esempio, una con un intervallo esattamente di un secondo e una con esattamente 1,5 secondi, questo dà il risultato 1.25 .