Как сравнить даты в полях datetime в Postgresql?
Я столкнулся с странным сценарием при сравнении дат в postgresql (версия 9.2.4 в окнах). У меня столбец в моей таблице говорит update_date с типом timestamp без часовой пояс. Клиент может осуществлять поиск по этому полю только с датой (например, 2013-05-03) или с датой со временем (т.е. 2013-05-03 12:20:00). Этот столбец имеет значение как временную метку для всех строк в настоящее время и имеет ту же дату (2013-05-03), но разницу во времени.
Когда я сравниваю этот столбец, я получаю разные результаты. Как и следующие:
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
Мой вопрос: как я могу сделать первый запрос возможным для получения результатов, я имею в виду, почему третий запрос работает, но не первый?
Может кто-нибудь мне помочь? Спасибо заранее.
Ответы
Ответ 1
@Nicolai правильно относится к кастингу и почему условие ложно для любых данных. я предполагаю, что вы предпочитаете первую форму, потому что хотите избежать манипуляции с датами на входной строке, правильно? вам не нужно бояться:
SELECT *
FROM table
WHERE update_date >= '2013-05-03'::date
AND update_date < ('2013-05-03'::date + '1 day'::interval);
Ответ 2
Когда вы сравниваете значения update_date >= '2013-05-03'
postgres, значения для одного и того же типа сравниваются. Таким образом, ваш "2013-05-03" был переведен на "2013-05-03 00:00:00".
Итак, для update_date = '2013-05-03 14:45:00' ваше выражение будет таким:
'2013-05-03 14:45:00' >= '2013-05-03 00:00:00' AND '2013-05-03 14:45:00' <= '2013-05-03 00:00:00'
Это всегда false
Чтобы решить эту проблему, добавьте update_date в date
:
select * from table where update_date::date >= '2013-05-03' AND update_date::date <= '2013-05-03' -> Will return result
Ответ 3
Используйте тип range
. Если пользователь вводит дату:
select *
from table
where
update_date
<@
tsrange('2013-05-03', '2013-05-03'::date + 1, '[)');
Если пользователь вводит временные метки, вам не нужна ::date + 1
часть
http://www.postgresql.org/docs/9.2/static/rangetypes.html
http://www.postgresql.org/docs/9.2/static/functions-range.html