2017-01-26 4 views
1

Um die Anzahl der Tage zwischen zwei Terminen finden wir so etwas wie diese verwenden:Wie kann man Tage außer Sonntag zwischen zwei Terminen in Postgres zählen?

SELECT date_part('day',age('2017-01-31','2017-01-01')) as total_days; 

In der obigen Abfrage wir 30 als Ausgang bekam statt 31. Warum ist das so?
Und ich möchte auch die Anzahl der Tage außer Sonntage finden. Erwartete Ausgabe für das Intervall ('2017-01-01', '2017-01-31'):

Total Days = 31 
Total Days except Sundays = 26 
+2

Unrelated, aber: 'date_part ('Tag', Alter ('2017.01.31', '2017.01.01')) gibt Ihnen ein falsches Ergebnis, wenn das "Alter" mehr als einen Monat beträgt. z.B. 'date_part ('Tag', Alter ('2016-02-28', '2016-01-01'))' würde 27 zurückgeben, obwohl es 58 sein sollte. Wenn Sie die Anzahl der Tage zwischen zwei Daten möchten, subtrahieren Sie sie einfach : 'Datum '2017-01-31' - Datum '2017-01-01'' –

+0

Danke @a_horse_with_no_name ... wird dies verwenden – Mani

Antwort

1

könnten Sie versuchen generate_series mit alle Termine zwischen bestimmten Zeitpunkt zu erzeugen und dann Anzahl der erforderlichen Tage dauern.

SELECT 
    count(case when extract(dow from generate_series) <> 0 then 1 end) n 
from generate_series('2017-01-01'::date,'2017-01-31'::date, '1 day'); 
3

Sie müssen "zwischen zwei Terminen" definieren enger. Unter- und Obergrenze enthalten oder ausgeschlossen? Eine übliche Definition wäre die untere und auszuschließen die obere Grenze eines Intervalls. Definieren Sie das Ergebnis außerdem als 0, wenn die untere und obere Grenze identisch sind. Diese Definition stimmt überein mit der Datumssubtraktion genau.

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 obere Grenze, so dass nur Sonntag subtrahiert werden kann.

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 ganzzahligen Ganzzahl (Tage/7) erhalten, die das Ergebnis abschneidet.

Der zusätzliche Sonntag für den Rest von 1 - 6 Tagen hängt vom ersten Tag des Intervalls ab. Wenn es ein Sonntag ist, Bingo; wenn es ein Montag ist, schade.

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; 

Werke für jedes bestimmtes Intervall: Etc. Wir können eine einfache Formel aus herleiten.
Hinweis: isodow, not dow for EXTRACT().

Um umfassen die obere Grenze, ersetzen Sie einfach z - a mit (z - a) + 1. (Würde ohne Klammern arbeiten, aufgrund Operator Vorrang, aber besser klar.)

Leistungscharakteristik ist O (1) (konstant), wie auf einen bedingten Aggregat über einen erzeugten Satz gegen mit O (N).

Verwandte:

Verwandte Themen