2014-04-28 11 views
46

Ich versuche, meine Postgresql-DB abzufragen, um Ergebnisse zurückgeben, wo ein Datum in bestimmten Monat und Jahr ist. Mit anderen Worten, ich möchte alle Werte für ein Monat-Jahr.Postgresql Abfrage zwischen den Datenbereichen

Der einzige Weg, ich habe in der Lage, es zu tun, so weit wie folgt aus:

SELECT user_id 
FROM user_logs 
WHERE login_date BETWEEN '2014-02-01' AND '2014-02-28' 

Problem dabei ist, dass ich das erste Datum und letzte Datum zu berechnen, bevor die Tabelle abzufragen. Gibt es einen einfacheren Weg, dies zu tun?

Dank

+0

Ist das Intervall immer ein Monat oder könnte es sein, dass Sie vielleicht am 15. beginnen und am 7. am Ende der folgenden Monat? – frlan

Antwort

89

Mit Daten (und Zeiten) viele Dinge einfacher geworden, wenn Sie >= start AND < end verwenden.

Zum Beispiel:

SELECT 
    user_id 
FROM 
    user_logs 
WHERE 
     login_date >= '2014-02-01' 
    AND login_date < '2014-03-01' 

In diesem Fall können Sie immer noch das Startdatum des Monats berechnen müssen Sie brauchen, aber das sollte in einem beliebigen Anzahl von Möglichkeiten, einfach sein.

Das Enddatum ist ebenfalls vereinfacht; füge genau einen Monat hinzu. Auch nicht schlecht über mit 28., 30., 31. usw.


Diese Struktur hat auch den Vorteil, dass die Verwendung von Indizes zu halten.


Viele Menschen können eine Form wie die folgenden vorschlagen, aber sie nicht Verwendung Indizes:

WHERE 
     DATEPART('year', login_date) = 2014 
    AND DATEPART('month', login_date) = 2 

Dabei werden die Bedingungen für jede einzelne Zeile in der Tabelle Berechnung (ein Scan) und nicht den Index verwenden, um den Bereich der Zeilen zu finden, die übereinstimmen (eine Bereichssuche).

+1

Der erste Ansatz muss mit Monaten (statt Tagen) foxen. '2014-12-01' &' 2015-01-01'. Die zweite kann auch indiziert werden, aber das ist nicht trivial, ich gebe zu - 'EXTRACT()' scheint kompatibler zu sein. – pozs

-7

Lesen Sie die Dokumentation.

http://www.postgresql.org/docs/9.1/static/functions-datetime.html

habe ich eine Abfrage wie folgt aus:

WHERE 
(
    date_trunc('day',table1.date_eval) = '2015-02-09' 
) 

oder

WHERE(date_trunc('day',table1.date_eval) >='2015-02-09'AND date_trunc('day',table1.date_eval) <'2015-02-09')  

Juanitos Ingenier.

+1

Dies beantwortet die Frage nicht genau. Die Frage fragt nach Daten basierend auf Monat und Jahr. – Ram

3

Von PostreSQL 9.2 werden Range Types unterstützt. So können Sie schreiben dies wie:

SELECT user_id 
FROM user_logs 
WHERE '[2014-02-01, 2014-03-01)'::daterange @> login_date 

dies effizienter sein sollte als der String-Vergleich

Verwandte Themen