sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL:mellan med datetime

Du förväntade dig 1-01-01 ... 1-12-31 ... men hur ska PostgreSQL veta vad du menar med det?

Inmatningssträngsliteralerna tolkas enligt inställningarna för din nuvarande session (som är standardinställningarna i postgressql.conf om det inte åsidosätts). I synnerhet datestyle :

DateStyle (string )

Ställer in visningsformatet för datum- och tidsvärden, samt reglerna för tolkning av tvetydiga datuminmatningsvärden. Av historiska skäl innehåller denna variabel två oberoende komponenter:utdataformatspecifikationen (ISO , Postgres , SQL , eller German ) och in-/utgångsspecifikationen för beställning av år/månad/dag (DMY , MDY , eller YMD ). Dessa kan ställas in separat eller tillsammans. NyckelordenEuro och European är synonymer till DMY; nyckelorden US ,NonEuro , och NonEuropean är synonymer till MDY . Se Avsnitt 8.5 för mer information. Den inbyggda standarden är ISO, MDY , men initdb kommer att initiera konfigurationsfilen med en inställning som motsvarar beteendet för den valda lc_time språk.

(Medan utdataformatet mestadels bestäms av lc_time .)

I ditt fall, den stympade tidsstämpeln bokstavlig 1-12-31 23:59:59 tolkas uppenbarligen som:

D-MM-YY h24:mi:ss

Medan du skulle ha hoppats på:

Y-MM-DD h24:mi:ss

3 alternativ

  1. Ställ in datestyle så att den tolkar bokstavliga ord på samma sätt som du gör. Kanske ISO, YMD ?

  2. Använd to_timestamp() att tolka strängen bokstavligt på ett väldefinierat sätt - oberoende av andra inställningar. Mycket bättre.

     SELECT to_timestamp('1-12-31 23:59:59', 'Y-MM-DD h24:mi:ss');
    
  3. Ännu bättre, använd ISO 8601-formatet (YYYY-MM-DD ) för alla datetime literals. Det är otvetydigt och oberoende av alla inställningar .

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

Skriv om frågan

Din fråga är felaktig till att börja med. Hantera intervallfrågor på olika sätt. Gilla:

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;

Eller ännu enklare:

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;

Områdestyper i PostgreSQL 9.2 eller senare kan vara av intresse.



  1. Bästa sättet att kontrollera om det finns tomt eller nullvärde

  2. Hur man installerar ODP.NET 2.111 och ODP.NET 4.112 i samma maskin sida vid sida medan båda pekar på samma databasserver

  3. Mysql-databassynkronisering mellan två databaser

  4. Top-N-frågor och paginering i Oracle