PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

PostgreSQL:entre com data e hora


Você esperava 1-01-01 ... 1-12-31 ... mas como o PostgreSQL deve saber o que você quer dizer com isso?

Os literais de string de entrada são interpretados de acordo com as configurações da sua sessão atual (que tem como padrão as configurações gerais em postgressql.conf a menos que seja rejeitado). Em particular datestyle :

DateStyle (string )

Define o formato de exibição para valores de data e hora, bem como as regras para interpretar valores de entrada de data ambíguos. Por razões históricas, esta variável contém dois componentes independentes:a especificação do formato de saída (ISO , Postgres , SQL , ou German ) e a especificação de entrada/saída para pedido de ano/mês/dia (DMY , MDY , ou YMD ). Estes podem ser definidos separadamente ou em conjunto. As palavras-chaveEuro e European são sinônimos de DMY; as palavras-chave US ,NonEuro , e NonEuropean são sinônimos de MDY . Consulte a Seção 8.5 Para maiores informações. O padrão interno é ISO, MDY , mas o initdb irá inicializar o arquivo de configuração com uma configuração que corresponde ao comportamento do lc_time escolhido localidade.

(Embora o formato de saída seja determinado principalmente por lc_time .)

No seu caso, o literal de carimbo de data/hora mutilado 1-12-31 23:59:59 é obviamente interpretado como:
D-MM-YY h24:mi:ss

Enquanto você esperava:
Y-MM-DD h24:mi:ss

3 opções


  1. Definir datestyle para que ele interprete literais da mesma maneira que você. Talvez ISO, YMD ?

  2. Use to_timestamp() para interpretar a string literal de uma forma bem definida - independente de outras configurações. Muito melhor.
     SELECT to_timestamp('1-12-31 23:59:59', 'Y-MM-DD h24:mi:ss');
    

  3. Melhor ainda, use o formato ISO 8601 (YYYY-MM-DD ) para todos os literais de data e hora. Isso é inequívoco e independente de qualquer configuração .
     SELECT '2001-12-31 23:59:59'::timestamp;
    

Reescrever consulta


Sua consulta está com defeito para começar. Lide com consultas de intervalo de maneira diferente. Como:
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;

Ou, mais simples ainda:
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;

Os tipos de intervalo no PostgreSQL 9.2 ou mais recente podem ser de interesse.