Musisz zdefiniować „między dwiema datami” uważniej. Dolna i górna granica uwzględniona czy wykluczona? Powszechną definicją byłoby uwzględnienie niższy i wyklucz górna granica przedziału. Dodatkowo zdefiniuj wynik jako 0, gdy dolna i górna granica są identyczne. Ta definicja zbiega się z odejmowaniem dat dokładnie .
SELECT date '2017-01-31' - date '2017-01-01' AS days_between
Ta dokładna definicja jest ważna dla wykluczenia niedziel. Dla podanej definicji odstęp od Słońca do Słońca (1 tydzień później) nie zawiera górnej granicy, więc jest tylko 1 Niedziela do odjęcia.
interval in days | sundays
0 | 0
1-6 | 0 or 1
7 | 1
8-13 | 1 or 2
14 | 2
...
Odstęp 7 dni zawsze obejmuje dokładnie jedną niedzielę.
Minimalny wynik możemy uzyskać za pomocą dzielenia przez zwykłe liczby całkowite (dni / 7 ), co obcina wynik.
Dodatkowa niedziela przez pozostałą część 1 - 6 dni zależy od pierwszego dnia przerwy. Jeśli jest niedziela, bingo; jeśli jest poniedziałek, szkoda. Itd. Z tego możemy wyprowadzić prosty wzór:
SELECT days, sundays, days - sundays AS days_without_sundays
FROM (
SELECT z - a AS days
, ((z - a) + EXTRACT(isodow FROM a)::int - 1 ) / 7 AS sundays
FROM (SELECT date '2017-01-02' AS a -- your interval here
, date '2017-01-30' AS z) tbl
) sub;
Działa dla każdego podany interwał.
Uwaga:isodow
, a nie dow
dla EXTRACT()
.
Aby uwzględnić górna granica, wystarczy zastąpić z - a
z (z - a) + 1
. (Działałoby bez nawiasów, ze względu na pierwszeństwo operatorów, ale lepiej żeby było jasne.)
Charakterystyka wydajności to O(1) (stała) w przeciwieństwie do agregacji warunkowej nad wygenerowanym zbiorem z O(N) .
Powiązane:
- Jak określić ostatni dzień poprzedniego miesiąca za pomocą PostgreSQL?
- Oblicz godziny pracy między 2 datami w PostgreSQL