Mam do czynienia z dziwnym scenariuszem podczas porównywania dat w postgresql (wersja 9.2.4 w systemie Windows). Mam kolumnę w tabeli, która mówi „update_date” z typem „timestamp without strefa czasowa”. Klient może wyszukiwać w tym polu tylko według daty (tj: 2013-05-03) lub daty z godziną (tj: 2013-05-03 12:20:00). Ta kolumna ma obecnie wartość znacznika czasu dla wszystkich wierszy i ma tę samą część daty (2013-05-03), ale różnicę w części czasu.
Porównując tę kolumnę, otrzymuję różne wyniki. Podobnie jak następujące:
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
Moje pytanie brzmi: w jaki sposób mogę umożliwić pierwsze zapytanie, aby uzyskać wyniki, mam na myśli, dlaczego trzecie zapytanie działa, ale nie pierwsze?
Czy ktoś może mi w tym pomóc? Z góry dziękuję.
źródło
'2013-05-03'::date
i'1 day'::interval
) PostgreSQL jest specyficzna?CAST('2013-05-03' AS DATE) + CAST('1 day' AS INTERVAL)
(IIRC). YMMV w sprawie istnienia i zachowaniaDATE
orazINTERVAL
.::DATE
dodać pierwszą część klauzuliWHERE update_date::date = '2013-05-03'
działałby tak dobrze, a może nieco bardziej czytelny?update_date
byłtimestamp without timezone
. założyłem indeks w tej kolumnie. Twój predykat nie używałby tego indeksu.Podczas porównywania
update_date >= '2013-05-03'
postgres rzutuje wartości na ten sam typ, aby porównać wartości. Twój „2013-05-03” został przesłany na „2013-05-03 00:00:00”.Tak więc dla update_date = '2013-05-03 14:45:00' twoje wyrażenie będzie takie:
Tak jest zawsze
false
Aby rozwiązać ten problem, wyślij update_date na
date
:źródło
update_date
w tabeli w porównaniu do rzutowania pojedynczej wartości parametru zapytania jest strasznie nieefektywne i zapewnia, że serwer nie będzie w stanie wykorzystać indeksów w tej kolumnie. kusi mnie -1 do tego.SELECT * FROM my_table WHERE update_date >= '2013-05-03' AND update_date < '2013-05-04';
(Zwróć uwagę na użycie 4 maja zamiast 3 i ze ZNAKIEM MNIEJSZYM NIŻ niższym niż lub równym.)Użyj tego
range
typu. Jeśli użytkownik wprowadzi datę:Jeżeli użytkownik wprowadzi znaczniki czasu wtedy nie trzeba się
::date + 1
udziałhttp://www.postgresql.org/docs/9.2/static/rangetypes.html
http://www.postgresql.org/docs/9.2/static/functions-range.html
źródło
Użyj funkcji Konwertuj datę, aby porównać z datą: Wypróbuj to:
źródło