Eu tenho enfrentado um cenário estranho ao comparar datas no postgresql (versão 9.2.4 no windows). Eu tenho uma coluna na minha tabela como update_date com o tipo 'timestamp without fuso horário'. O cliente pode pesquisar nesse campo apenas com data (por exemplo: 2013-05-03) ou data com hora (por exemplo: 2013-05-03 12:20:00). Esta coluna possui o valor como carimbo de data e hora para todas as linhas atualmente e tem a mesma parte da data (03/05/2013), mas diferença na parte da hora.
Quando estou comparando esta coluna, estou obtendo resultados diferentes. Como os seguintes:
select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-03' -> No results
select * from table where update_date >= '2013-05-03' AND update_date < '2013-05-03' -> No results
select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-04' -> results found
select * from table where update_date >= '2013-05-03' -> results found
Minha pergunta é como posso tornar possível a primeira consulta para obter resultados. Quero dizer, por que a terceira consulta está funcionando, mas não a primeira?
Alguém pode me ajudar com isso? Desde já, obrigado.
fonte
'2013-05-03'::date
e'1 day'::interval
) o PostgreSQL é específica?CAST('2013-05-03' AS DATE) + CAST('1 day' AS INTERVAL)
(IIRC). YMMV sobre a existência e comportamento deDATE
eINTERVAL
.::DATE
adicionado à primeira parte da cláusula ondeWHERE update_date::date = '2013-05-03'
funcionaria tão bem e talvez um pouco mais legível?update_date
eratimestamp without timezone
. Eu assumi um índice nessa coluna. seu predicado não usaria esse índice.Quando você compara o
update_date >= '2013-05-03'
postgres, lança valores para o mesmo tipo para comparar valores. Portanto, seu '2013-05-03' foi transmitido para '2013-05-03 00:00:00'.Portanto, para update_date = '2013-05-03 14:45:00', sua expressão será a seguinte:
Isso é sempre
false
Para resolver esse problema, transmita update_date para
date
:fonte
update_date
tabela da lista vs. converter o valor único do parâmetro de consulta é terrivelmente ineficiente e garante que o servidor não possa aproveitar os índices nessa coluna. Estou tentado a -1 disso.SELECT * FROM my_table WHERE update_date >= '2013-05-03' AND update_date < '2013-05-04';
(Observe o uso de 4 de maio em vez de 3 e com um sinal menor que igual a menor ou igual.)Use o
range
tipo Se o usuário digitar uma data:Se o usuário digitar registros de data e hora, você não precisará da
::date + 1
partehttp://www.postgresql.org/docs/9.2/static/rangetypes.html
http://www.postgresql.org/docs/9.2/static/functions-range.html
fonte
Use a conversão de data para comparar com a data: tente isto:
fonte