Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle sqlSubtract zwischen zwei Daten

Ich nehme an, das sind Hausaufgaben, also ein paar Hinweise...

Erstens:Daten nie als varchar speichern , es wird Ihnen und dem Optimierer alle möglichen Probleme bereiten.

Zweitens das date von Oracle datatype kann nur mit Sekundengenauigkeit speichern, und Ihre Zeichenfolge hat Sekundenbruchteile, also sehen Sie sich Zeitstempel statt Datum . Sie können Ihren String mit to_timestamp() Funktion, wobei eine geeignete Formatmaske übergeben wird . Oh OK, ich fühle mich großzügig:

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

Drittens erhalten Sie durch Subtrahieren von zwei Zeitstempeln einen Intervall Datentyp, aus dem Sie die gewünschten Informationen in einem lesbaren Format extrahieren müssen. Suchen Sie auf dieser Website oder anderswo nach Zeitstempel-Subtraktion, aber ich verweise Sie auf diese aktuelle als Beispiel.

Der Durchschnitt ist etwas kniffliger, daher möchten Sie vielleicht Ihre Intervalle dafür in Zahlen umwandeln; Suchen Sie erneut nach vorherigen Fragen, wie z. B. dieser . Die Größe der Intervalle, die Genauigkeit, die Ihnen wirklich wichtig ist, und die Art und Weise, wie Sie die Ausgabe formatieren möchten, usw., werden einen Einfluss auf die Vorgehensweise haben, die Sie wählen möchten.

Wenn Sie ein ungefähres Ergebnis benötigen, erhalten Sie in der Antwort von @Joachim Isaksson das - "ungefähr" wegen Rundung; eine Dauer von weniger als einer Sekunde wird beispielsweise als Null angezeigt. Der gleiche Effekt ist bei Zeitstempeln zu sehen, die in Datumsangaben umgewandelt werden, wodurch auch die Sekundenbruchteile verloren gehen:

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;

Eine genauere Antwort kann gefunden werden, indem die verschiedenen Komponenten der Zeitstempel extrahiert werden, wie in einer Frage, die ich zuvor verlinkt habe. Sie benötigen sie möglicherweise nicht alle, wenn Sie wissen, dass Ihre Dauer beispielsweise immer weniger als eine Stunde beträgt, aber wenn Sie mehr als eine benötigen (dh wenn eine Dauer länger als eine Minute sein könnte), vereinfacht die Verwendung eines gemeinsamen Zwischentabellenausdrucks die Dinge a bisschen:

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;

Bei zwei Probenzeilen, eine mit genau einer Sekunde und eine mit genau 1,5 Sekunden Abstand, ergibt dies das Ergebnis 1.25 .