Mam takie zapytanie:
SELECT * FROM Cases WHERE created_at BETWEEN '2013-05-01' AND '2013-05-01'
Ale to nie daje żadnych wyników, mimo że istnieją dane z 1.
created_at
wygląda na to 2013-05-01 22:25:19
, podejrzewam, że ma to związek z czasem? Jak można to rozwiązać?
Działa dobrze, jeśli robię większe zakresy dat, ale powinno (włącznie) działać również z jedną datą.
sql
sql-server
sql-server-2008
tsql
date
JBurace
źródło
źródło
Odpowiedzi:
To jest w cenie. Porównujesz czas dat z datami. Druga data jest interpretowana jako północ, gdy zaczyna się dzień .
Jednym ze sposobów rozwiązania tego problemu jest:
Innym sposobem rozwiązania tego problemu są jawne porównania binarne
Aaron Bertrand ma na blogu długi wpis dotyczący dat ( tutaj ), w którym omawia ten i inne kwestie związane z datami.
źródło
dateadd
aby uzyskać następny dzień.set dateformat dmy;select month(cast('2013-05-01' as datetime)); =1
>=
) i otwartego na drugim (<
) w połączeniu ze sprawdzaniem jednego dnia po określonej dacie zakończenia.where
klauzuli, ponieważ utraci ona wszelkie posiadane indeksy. To naprawdę zły wzór.Założono, że drugie odniesienie do daty w
BETWEEN
składni jest magicznie uważane za „koniec dnia”, ale to nieprawda .czyli oczekiwano:
ale to, co naprawdę się wydarzyło, to:
Co staje się odpowiednikiem:
Problemem jest to jedna z percepcji / oczekiwań o
BETWEEN
których nie obejmują zarówno dolną i górną wartość wartości w przedziale, ale nie magicznie zrobić data „początek” i „koniec”.BETWEEN
należy unikać filtrowania według zakresów dat.Zawsze używaj
>= AND <
zamiast tegonawiasy są tutaj opcjonalne, ale mogą być ważne w bardziej złożonych zapytaniach.
źródło
Musisz zrobić jedną z tych dwóch opcji:
between
stanie:... where created_at between '2013-05-01 00:00:00' and '2013-05-01 23:59:59'
(niezalecane ... zobacz ostatni akapit)between
. Zauważ, że wtedy będziesz musiał dodać jeden dzień do drugiej wartości:... where (created_at >= '2013-05-01' and created_at < '2013-05-02')
Moje osobiste preferencje to druga opcja. Również Aaron Bertrand ma bardzo jasne wyjaśnienie, dlaczego należy go stosować.
źródło
BETWEEN
do zapytań dotyczących zakresu dat, które obejmują czas; zbyt wiele może się nie udać.Po prostu użyj znacznika czasu jako daty:
źródło
'DATE' is not a recognized built-in function name.
trzeba przekonwertować stackoverflow.com/a/20973452/4233593Uważam, że najlepszym rozwiązaniem do porównywania pola daty i godziny z polem daty jest:
Jest to równoważne z instrukcją włączającą między, ponieważ zawiera zarówno datę początkową, jak i końcową, a także te, które przypadają między.
źródło
To zadziała tylko w 2008 i nowszych wersjach SQL Server
Jeśli używasz starszej wersji, użyj
źródło
convert(varchar, created_at, 101)
wynik jest podobny,dd/MM/yyyy
a stringi OP sąyyyy-MM-dd
, myślę, że ta odpowiedź nie zadziała;).Możesz użyć
date()
funkcji, która wyodrębni datę z daty i godziny i poda wynik jako datę włącznie:źródło
Data dyamic BETWEEN zapytanie sql
źródło