PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL:tra con datetime

Ti aspettavi 1-01-01 ... 1-12-31 ... ma come dovrebbe PostgreSQL a sapere cosa intendi con questo?

I valori letterali della stringa di input vengono interpretati in base alle impostazioni della sessione corrente (che per impostazione predefinita sono le impostazioni generali in postgressql.conf a meno che non venga annullato). In particolare datestyle :

DateStyle (string )

Imposta il formato di visualizzazione per i valori di data e ora, nonché le regole per interpretare i valori di input della data ambigui. Per ragioni storiche, questa variabile contiene due componenti indipendenti:la specifica del formato di output (ISO , Postgres , SQL o German ) e le specifiche di input/output per l'ordine di anno/mese/giorno (DMY , MDY , o YMD ). Questi possono essere impostati separatamente o insieme. Le parole chiaveEuro e European sono sinonimi di DMY; le parole chiave US ,NonEuro e NonEuropean sono sinonimi di MDY . Vedi Sezione 8.5 per maggiori informazioni. L'impostazione predefinita è ISO, MDY , ma initdb inizializzerà il file di configurazione con un'impostazione che corrisponde al comportamento del lc_time scelto locale.

(Mentre il formato di output è principalmente determinato da lc_time .)

Nel tuo caso, il timestamp letterale mutilato 1-12-31 23:59:59 è ovviamente interpretato come:

D-MM-YY h24:mi:ss

Mentre avresti sperato in:

Y-MM-DD h24:mi:ss

3 opzioni

  1. Imposta datestyle in modo che interpreti i letterali nello stesso modo in cui lo fai tu. Forse ISO, YMD ?

  2. Usa to_timestamp() per interpretare la stringa letterale in un modo ben definito, indipendentemente da altre impostazioni. Molto meglio.

     SELECT to_timestamp('1-12-31 23:59:59', 'Y-MM-DD h24:mi:ss');
    
  3. Meglio ancora, usa il formato ISO 8601 (YYYY-MM-DD ) per tutti i valori letterali datetime. Questo è non ambiguo e indipendente da qualsiasi impostazione .

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

Riscrivi query

La tua richiesta è errata tanto per cominciare. Gestisci le query di intervallo in modo diverso. Come:

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;

Oppure, ancora più semplice:

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;

I tipi di intervallo in PostgreSQL 9.2 o versioni successive potrebbero essere di interesse.