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

Unterschied zwischen zwei Werten für Jahr, Monat und Tag in Oracle

Wenn Sie gründlich darüber nachdenken, werden Sie feststellen, dass Sie keine Differenz von zwei "Zeitintervallen" berechnen können, wenn Monate vorhanden sind; einfach, weil eine Subtraktion von Monaten zu einer anderen Anzahl von Tagen führen kann. Sie können Jahre subtrahieren, Sie können Wochen subtrahieren, Sie können Tage subtrahieren, ... Sie können Tage von Sekunden subtrahieren, Sie können Jahre von Monaten subtrahieren. Sie können jedoch nicht Jahre von Tagen subtrahieren.

Beispiel:

SQL> select timestamp'1915-07-23 00:00:00' - timestamp'1907-09-12 00:00:00' as diff_day_to_second_interval from dual;

DIFF_DAY_TO_SECOND_INTERVAL
---------------------------
+000002871 00:00:00

Dies sind Ihre 15 Jahre, 7 Monate, 23 Tage minus 7 Jahre, 9 Monate, 12 Tage basierend auf dem 1. Januar 1900. Dies ergab eine Differenz von 2871 Tagen.

Betrachten Sie jedoch die folgenden zwei Beispiele, die einfach um 1 und 6 Monate in die Vergangenheit verschoben wurden

select timestamp'1915-06-23 00:00:00' - timestamp'1907-08-12 00:00:00' as diff_day_to_second_interval from dual;

DIFF_DAY_TO_SECOND_INTERVAL
---------------------------
+000002872 00:00:00

select timestamp'1915-01-23 00:00:00' - timestamp'1907-03-12 00:00:00' as diff_day_to_second_interval from dual;

DIFF_DAY_TO_SECOND_INTERVAL
---------------------------
+000002874 00:00:00

SQL> 

Diese gaben uns nun 2872 und 2874 Tage Unterschied.

Apropos mögliche Subtraktionen...

(a) Subtrahieren von Jahr-zu-Monat-Intervallen

SQL> select interval'1915-07' year(4) to month - interval'1907-09' year(4) to month as diff_year_to_month_interval from dual;

DIFF_YEAR_TO_MONTH_INTERVAL
---------------------------
+000000007-10

select interval'1915-06' year(4) to month - interval'1907-08' year(4) to month as diff_year_to_month_interval from dual;

DIFF_YEAR_TO_MONTH_INTERVAL
---------------------------
+000000007-10

select interval'1915-01' year(4) to month - interval'1907-03' year(4) to month as diff_year_to_month_interval from dual;

DIFF_YEAR_TO_MONTH_INTERVAL
---------------------------
+000000007-10

SQL> 

Alle drei ergeben korrekterweise eine Differenz von 7 Jahren und 10 Monaten.

(b) Subtrahieren von Tag-zu-Sekunden-Intervallen

SQL> select interval'15 01:02:03' day(2) to second - interval'07 02:03:04' day(2) to second as diff_day_to_second_interval from dual;

DIFF_DAY_TO_SECOND_INTERVAL
---------------------------
+000000007 22:58:59

select interval'14 00:01:02' day(2) to second - interval'06 01:02:03' day(2) to second as diff_day_to_second_interval from dual;

DIFF_DAY_TO_SECOND_INTERVAL
---------------------------
+000000007 22:58:59

select interval'09 11:12:13' day(2) to second - interval'01 12:13:14' day(2) to second as diff_day_to_second_interval from dual;

DIFF_DAY_TO_SECOND_INTERVAL
---------------------------
+000000007 22:58:59

SQL> 

Alle drei führen zu denselben Ergebnissen, da alle drei Subtraktionen von Tag-zu-Sekunde-Intervallen mit konsistenter Verrechnung der Tag/Stunde/Minute/Sekunde-Teile der Intervallwerte sind.

(c) Subtrahieren von Jahr-zu-Tag-Intervallen

Wie gesagt:nicht möglich. Es gibt nicht einmal so etwas wie ein Jahr-zu-Tag-Intervall in Oracle; Hersteller des DB-Servers wussten, warum sie beschlossen, diese nicht zur Engine hinzuzufügen.