W tabeli artykuly (kolumna cena) chcemy wybrać artykuły, których cena NIE mieści się w przedziale od 1000 do 1500 zł. Którego warunku WHERE należy użyć?
Warunek cena NOT BETWEEN 1000 AND 1500 jest właściwy, bo dokładnie opisuje sytuację: wybieramy rekordy, w których wartość kolumny cena znajduje się poza podanym zakresem. W SQL operator BETWEEN sprawdza przedział domknięty, czyli cena BETWEEN 1000 AND 1500 oznacza ceny od 1000 do 1500 włącznie. Dodanie NOT odwraca ten warunek, więc zostaną wybrane artykuły z ceną mniejszą niż 1000 albo większą niż 1500. W praktyce jest to równoważne zapisowi cena < 1000 OR cena > 1500. To ważne, bo granice 1000 i 1500 też są traktowane jako należące do przedziału, więc przy NOT BETWEEN nie zostaną pokazane. Moim zdaniem ten zapis jest też najbardziej czytelny dla kogoś, kto później będzie utrzymywał zapytanie. W bazach danych czytelność warunków WHERE ma duże znaczenie, szczególnie w raportach, filtrach sklepów internetowych albo panelach administracyjnych, gdzie łatwo pomylić AND z OR. Dobra praktyka jest taka, żeby stosować operatory SQL zgodnie z ich znaczeniem semantycznym, a tutaj NOT BETWEEN jasno mówi: poza zakresem.
W tym pytaniu kluczowe jest zrozumienie, że przedział od 1000 do 1500 zł oznacza wszystkie wartości mieszczące się między tymi liczbami, razem z granicami. Sam zapis cena BETWEEN 1000 AND 1500 robi coś odwrotnego niż potrzeba, bo zwraca artykuły, których cena jest właśnie w tym zakresie. To częsty błąd, bo operator BETWEEN wygląda wygodnie i kojarzy się z przedziałem, ale bez NOT nie ma tu żadnego wykluczenia. Z mojego doświadczenia takie pomyłki często wychodzą dopiero przy testowaniu danych granicznych, na przykład ceny równej dokładnie 1000 albo 1500. Warunek cena < 1000 AND cena > 1500 też nie zadziała, ponieważ jedna cena nie może być jednocześnie mniejsza od 1000 i większa od 1500. Logicznie taki warunek jest sprzeczny, więc dla normalnych wartości liczbowych nie zwróci żadnych rekordów. Gdy chcemy opisać wartości poza zakresem ręcznie, trzeba użyć OR, czyli cena < 1000 OR cena > 1500. Zapis cena NOT IN (1000, 1500) również nie jest dobrym rozwiązaniem, bo wyklucza tylko dwie konkretne wartości: 1000 i 1500. Nadal przepuści na przykład cenę 1200, która przecież leży w zakazanym przedziale. To jest mylenie listy wartości z zakresem liczbowym. W SQL operator IN służy do porównania z konkretnym zbiorem elementów, a BETWEEN do pracy z przedziałami. W profesjonalnych zapytaniach WHERE warto dobierać operator do sensu biznesowego warunku, bo inaczej raport może wyglądać poprawnie składniowo, ale pokazywać kompletnie złe dane.