PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL:zwischen mit datetime

Sie haben 1-01-01 ... 1-12-31 erwartet ... aber woher soll PostgreSQL wissen, was Sie damit meinen?

Literale Eingabezeichenfolgen werden gemäß den Einstellungen Ihrer aktuellen Sitzung interpretiert (die standardmäßig die allgemeinen Einstellungen in postgressql.conf sind sofern nicht aufgehoben). Insbesondere datestyle :

DateStyle (string )

Legt das Anzeigeformat für Datums- und Uhrzeitwerte sowie die Regeln für die Interpretation mehrdeutiger Datumseingabewerte fest. Aus historischen Gründen enthält diese Variable zwei unabhängige Komponenten:die Angabe des Ausgabeformats (ISO , Postgres , SQL , oder German ) und die Eingabe-/Ausgabespezifikation für die Reihenfolge Jahr/Monat/Tag (DMY , MDY , oder YMD ). Diese können separat oder zusammen eingestellt werden. Die SchlüsselwörterEuro und European sind Synonyme für DMY; die Schlüsselwörter US ,NonEuro , und NonEuropean sind Synonyme für MDY . Siehe Abschnitt 8.5 für mehr Informationen. Der eingebaute Standard ist ISO, MDY , aber initdb initialisiert die Konfigurationsdatei mit einer Einstellung, die dem Verhalten der gewählten lc_time entspricht Gebietsschema.

(Während das Ausgabeformat hauptsächlich von lc_time bestimmt wird .)

In Ihrem Fall das verstümmelte Zeitstempel-Literal 1-12-31 23:59:59 wird offensichtlich interpretiert als:

D-MM-YY h24:mi:ss

Während Sie gehofft hätten:

Y-MM-DD h24:mi:ss

3 Optionen

  1. Legen Sie datestyle fest damit es Literale genauso interpretiert wie Sie. Vielleicht ISO, YMD ?

  2. Verwenden Sie to_timestamp() um das String-Literal wohldefiniert zu interpretieren - unabhängig von anderen Einstellungen. Viel besser.

     SELECT to_timestamp('1-12-31 23:59:59', 'Y-MM-DD h24:mi:ss');
    
  3. Besser noch, verwenden Sie das ISO 8601-Format (YYYY-MM-DD ) für alle datetime-Literale. Das ist eindeutig und unabhängig von jeglichen Einstellungen .

     SELECT '2001-12-31 23:59:59'::timestamp;
    

Abfrage neu schreiben

Ihre Abfrage ist zunächst fehlerhaft. Behandeln Sie Bereichsabfragen anders. Wie:

SELECT d.given_on 
FROM   documents_document d
WHERE  EXTRACT('month' FROM d.given_on) = 1
AND    d.given_on >= '2001-01-01 0:0'
AND    d.given_on <  '2002-01-01 0:0'
ORDER  BY d.created_on DESC;

Oder noch einfacher:

SELECT d.given_on 
FROM   documents_document d
WHERE  d.given_on >= '2001-01-01 0:0'
AND    d.given_on <  '2001-02-01 0:0'
ORDER  BY d.created_on DESC;

Bereichstypen in PostgreSQL 9.2 oder neuer könnten von Interesse sein.