Kiedy dokładnie się nad tym zastanowisz, zdasz sobie sprawę, że nie możesz obliczyć różnicy dwóch „przedziałów czasowych”, gdy istnieją miesiące; po prostu dlatego, że odjęcie miesięcy może skutkować różną liczbą dni. Możesz odjąć lata, możesz odjąć tygodnie, możesz odjąć dni... możesz odjąć dni do sekund, możesz odjąć lata do miesięcy. Nie można jednak odjąć z roku na dzień.
Przykład:
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
To jest twoje 15 lat, 7 miesięcy, 23 dni minus 7 lat, 9 miesięcy, 12 dni w oparciu o 1 stycznia 1900. Dało nam to 2871 dni różnicy.
Rozważ jednak następujące dwa przykłady, po prostu przesunięte o 1 i 6 miesięcy w przeszłość
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>
Dało nam to teraz 2872 i 2874 dni różnicy.
A teraz mowa o możliwych odejmowaniach...
(a) odejmowanie interwałów rocznych
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>
Wszystkie trzy prawidłowo dają różnicę 7 lat i 10 miesięcy.
(b) odejmowanie interwałów z dnia na sekundę
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>
Wszystkie trzy dają takie same wyniki, ponieważ wszystkie trzy są odejmowaniem interwałów z dnia na sekundę ze spójnym przesunięciem części dnia/godziny/minuty/sekundy wartości interwału.
(c) odejmowanie interwałów z roku na dzień
Jak powiedziałem:Niemożliwe. W Oracle nie ma nawet przerwy z roku na dzień; twórcy serwera DB wiedzieli, dlaczego zdecydowali się nie dodawać ich do silnika.