Sie müssen "zwischen zwei Daten" definieren genauer. Untere und obere Grenze eingeschlossen oder ausgeschlossen? Eine gebräuchliche Definition wäre einschließen die untere und ausschließen die obere Grenze eines Intervalls. Definieren Sie außerdem das Ergebnis als 0, wenn Unter- und Obergrenze identisch sind. Diese Definition stimmt zufällig genau mit der Datumssubtraktion überein .
SELECT date '2017-01-31' - date '2017-01-01' AS days_between
Diese genaue Definition ist wichtig, um Sonntage auszuschließen. Für die gegebene Definition enthält ein Intervall von Sonne - Sonne (1 Woche später) nicht die Obergrenze, also gibt es nur 1 Sonntag zu subtrahieren.
interval in days | sundays
0 | 0
1-6 | 0 or 1
7 | 1
8-13 | 1 or 2
14 | 2
...
Ein Intervall von 7 Tagen beinhaltet immer genau einen Sonntag.
Wir können das minimale Ergebnis mit einer einfachen ganzzahligen Division erhalten (days / 7 ), wodurch das Ergebnis abgeschnitten wird.
Der zusätzliche Sonntag für die restlichen 1 - 6 Tage hängt vom ersten Tag des Intervalls ab. Wenn es ein Sonntag ist, Bingo; wenn es ein Montag ist, schade. Usw. Daraus können wir eine einfache Formel ableiten:
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;
Funktioniert für alle angegebenen Intervall.
Hinweis:isodow
, nicht dow
für EXTRACT()
.
Zum Einschließen die Obergrenze, ersetzen Sie einfach z - a
mit (z - a) + 1
. (Würde aufgrund der Operatorpriorität ohne Klammern funktionieren, aber besser klar sein.)
Leistungsmerkmal ist O(1) (Konstante) im Gegensatz zu einem bedingten Aggregat über eine generierte Menge mit O(N) .
Verwandte:
- Wie ermittle ich den letzten Tag des Vormonats mit PostgreSQL?
- Arbeitszeit zwischen 2 Daten in PostgreSQL berechnen