sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL:tussen met datetime

Je had verwacht 1-01-01 ... 1-12-31 ... maar hoe moet PostgreSQL weten wat je daarmee bedoelt?

Letterlijke invoertekenreeksen worden geïnterpreteerd volgens de instellingen van uw huidige sessie (die standaard zijn ingesteld op algemene instellingen in postgressql.conf tenzij overruled). In het bijzonder datestyle :

DateStyle (string )

Stelt het weergaveformaat in voor datum- en tijdwaarden, evenals de regels voor het interpreteren van dubbelzinnige datuminvoerwaarden. Om historische redenen bevat deze variabele twee onafhankelijke componenten:de specificatie van het uitvoerformaat (ISO , Postgres , SQL , of German ) en de invoer/uitvoerspecificatie voor jaar/maand/dag-bestelling (DMY , MDY ,of YMD ). Deze kunnen afzonderlijk of samen worden ingesteld. De trefwoordenEuro en European zijn synoniemen voor DMY; de trefwoorden US ,NonEuro , en NonEuropean zijn synoniemen voor MDY . Zie Sectie 8.5 voor meer informatie. De ingebouwde standaard is ISO, MDY , maar initdb zal het configuratiebestand initialiseren met een instelling die overeenkomt met het gedrag van de gekozen lc_time landinstelling.

(Terwijl het uitvoerformaat meestal wordt bepaald door lc_time .)

In jouw geval is het verminkte tijdstempel letterlijk 1-12-31 23:59:59 wordt duidelijk geïnterpreteerd als:

D-MM-YY h24:mi:ss

Terwijl je had gehoopt:

Y-MM-DD h24:mi:ss

3 opties

  1. Stel datestyle in zodat het letterlijke op dezelfde manier interpreteert als jij. Misschien ISO, YMD ?

  2. Gebruik to_timestamp() om de tekenreeks letterlijk op een goed gedefinieerde manier te interpreteren - onafhankelijk van andere instellingen. Veel beter.

     SELECT to_timestamp('1-12-31 23:59:59', 'Y-MM-DD h24:mi:ss');
    
  3. Beter nog, gebruik ISO 8601-formaat (YYYY-MM-DD ) voor alle datetime-letterwoorden. Dat is ondubbelzinnig en onafhankelijk van welke instellingen dan ook .

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

Vraag opnieuw schrijven

Uw vraag is om te beginnen al defect. Behandel bereikquery's anders. Vind ik leuk:

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;

Of, nog eenvoudiger:

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;

Bereiktypen in PostgreSQL 9.2 of nieuwer kunnen interessant zijn.



  1. Connectiviteit van de beschikbaarheidsgroep configureren

  2. Wat is het SYSNAME-gegevenstype in SQL Server?

  3. Ontdek de geschiedenis van SQL-query's

  4. Verzamelmethoden:EERSTE &LAATSTE functies in Oracle Database