W SQL Server 2000 i 2005:
- jaka jest różnica między tymi dwoma
WHERE
klauzulami? - którego powinienem używać w jakich scenariuszach?
Zapytanie 1:
SELECT EventId, EventName
FROM EventMaster
WHERE EventDate BETWEEN '10/15/2009' AND '10/18/2009'
Zapytanie 2:
SELECT EventId, EventName
FROM EventMaster
WHERE EventDate >='10/15/2009'
AND EventDate <='10/18/2009'
(Edycja: pierwotnie brakowało drugiej Eventdate, więc zapytanie było błędne pod względem składniowym)
Odpowiedzi:
Są identyczne:
BETWEEN
to skrót dla dłuższej składni w pytaniu.Użyj alternatywnej dłuższej składni, gdzie
BETWEEN
nie działa, np(Uwaga
<
raczej niż<=
w drugim stanie).źródło
Oni są tacy sami.
Jedną rzeczą, na którą należy uważać, jest to, że jeśli używasz tego przeciwko DATETIME, data końcowa będzie zgodna z początkiem dnia:
to nie to samo co:
(to byłoby dopasować przeciwko
<= 20/10/2009 00:00:00.000
)źródło
Chociaż
BETWEEN
jest łatwy do odczytania i utrzymania, rzadko polecam jego użycie, ponieważ jest to przedział zamknięty i jak wspomniano wcześniej może to być problem z datami - nawet bez składników czasowych.Na przykład, gdy mamy do czynienia z danymi miesięcznymi, często porównuje się daty
BETWEEN first AND last
, ale w praktyce zwykle jest to łatwiejsze do zapisaniadt >= first AND dt < next-first
(co również rozwiązuje kwestię części czasu) - ponieważ określenielast
zwykle jest o jeden krok dłuższe niż ustalenienext-first
(odejmując dzień) .Ponadto inną przeszkodą jest to, że dolne i górne granice muszą być określone we właściwej kolejności (tj
BETWEEN low AND high
.).źródło
Zwykle nie ma różnicy -
BETWEEN
słowo kluczowe nie jest obsługiwane na wszystkich platformach RDBMS, ale jeśli tak jest, oba zapytania powinny być identyczne.Ponieważ są identyczne, tak naprawdę nie ma różnicy pod względem szybkości ani czegokolwiek innego - użyj tego, który wydaje ci się bardziej naturalny.
źródło
Jak wspomnieli @marc_s, @Cloud i in. są w zasadzie takie same dla zamkniętego zakresu.
Jednak wszelkie ułamkowe wartości czasu mogą powodować problemy z zamkniętym zakresem (większy lub równy i mniejszy lub równy ) w przeciwieństwie do półotwartego zakresu (większy lub równy i mniejszy niż ) z wartością końcową po ostatnia możliwa chwila.
Aby uniknąć sytuacji, w której zapytanie powinno zostać przepisane jako:
Ponieważ
BETWEEN
nie działa w półotwartych odstępach czasu, zawsze uważnie przyglądam się każdemu zapytaniu o datę / godzinę, które go używa, ponieważ prawdopodobnie jest to błąd.źródło
Mam pewne preferencje,
BETWEEN
ponieważ od razu daje czytelnikowi do zrozumienia, że sprawdzasz jedno pole dla zakresu . Jest to szczególnie ważne, jeśli masz podobne nazwy pól w tabeli.Jeśli, powiedzmy, nasza tabela ma zarówno a, jak
transactiondate
i atransitiondate
, jeśli czytamWiem od razu, że oba końce testu są przeciwko tej jednej dziedzinie.
Jeśli czytam
Muszę poświęcić dodatkową chwilę, aby upewnić się, że oba pola są takie same.
Ponadto, gdy zapytanie jest z czasem edytowane, niechlujny programista może rozdzielić te dwa pola. Widziałem wiele zapytań, które mówią coś w rodzaju
Jeśli spróbują tego z
BETWEEN
, oczywiście, będzie to błąd składniowy i szybko naprawiony.źródło
Myślę, że jedyną różnicą jest ilość cukru składniowego w każdym zapytaniu. BETWEEN to po prostu sprytny sposób powiedzenia dokładnie tego samego, co drugie zapytanie.
Mogą istnieć pewne specyficzne różnice w RDBMS, których nie jestem świadomy, ale tak naprawdę nie sądzę.
źródło
Logicznie rzecz biorąc, nie ma żadnej różnicy. Jeśli chodzi o wydajność, zazwyczaj w większości systemów DBMS nie ma żadnej różnicy.
źródło
Zobacz tę doskonałą blogu od Aaron Bertrand o których warto zmienić format string i jak wartości graniczne są obsługiwane w zapytaniach zakres dat.
źródło
Zastrzeżenie: wszystko poniżej jest tylko anegdotyczne i zaczerpnięte bezpośrednio z mojego osobistego doświadczenia. Każdy, kto czuje się na siłach, aby przeprowadzić bardziej rygorystyczną analizę empiryczną, może ją przeprowadzić i głosować przeciw. Zdaję sobie również sprawę, że SQL jest językiem deklaratywnym i nie powinieneś zastanawiać się, JAK przetwarzany jest twój kod, kiedy go piszesz, ale ponieważ cenię swój czas, tak.
Istnieje nieskończona liczba logicznie równoważnych instrukcji, ale rozważę trzy (ish).
Przypadek 1: Dwa porównania w standardowej kolejności (ustalona kolejność oceny)
Przypadek 2: cukier syntaktyczny (kolejność oceny nie jest wybierana przez autora)
Przypadek 3: Dwa porównania w uporządkowanej kolejności (kolejność oceny wybrana podczas pisania)
Lub
Z mojego doświadczenia wynika, że przypadek 1 i przypadek 2 nie mają żadnych spójnych ani zauważalnych różnic w wydajności, ponieważ nie znają zestawu danych.
Jednak przypadek 3 może znacznie skrócić czas wykonywania. W szczególności, jeśli pracujesz z dużym zestawem danych i zdarza się, że masz pewną heurystyczną wiedzę na temat tego, czy A jest bardziej prawdopodobne, że będzie większe niż MaxBound, czy mniejsze niż MinBound , możesz znacznie poprawić czasy wykonywania, używając przypadku 3 i porządkując porównania odpowiednio.
Jednym z moich przypadków użycia jest odpytywanie dużego historycznego zbioru danych z nieindeksowanymi datami dla rekordów w określonym przedziale czasu. Pisząc zapytanie, będę wiedział, czy istnieje więcej danych PRZED określonym interwałem lub PO określonym interwale i mogę odpowiednio uporządkować moje porównania. Czas wykonania został skrócony nawet o połowę w zależności od rozmiaru zbioru danych, złożoności zapytania i liczby rekordów przefiltrowanych przez pierwsze porównanie.
źródło
A
jest większe od obu granic, po prostu sprawdź, czyA
jest większe niżMaxBound
. Twój post wymaga dostosowania.W tym scenariuszu
col BETWEEN ... AND ...
icol <= ... and col >= ...
są równoważne.SQL Standard definiuje również predykat T461 Symmetric BETWEEN :
BETWEEN
wymaga sortowania wartości. Na przykład:Z drugiej strony:
Działa dokładnie tak, jak normalnie,
BETWEEN
ale po posortowaniu wartości porównawczych.db <> fiddle demo
źródło