Menu

Klauzula WHERE w SQLite: filtrowanie wierszy, LIKE, IN, BETWEEN

Jak klauzula WHERE filtruje wiersze w SQLite: operatory porównania, AND/OR, LIKE, IN, BETWEEN i pułapka z NULL, na którą łapie się każdy.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

WHERE filtruje wiersze po kolei

SELECT bez WHERE zwraca każdy wiersz tabeli. Rzadko o to chodzi. WHERE pozwala zostawić tylko wiersze spełniające warunek: SQLite przechodzi przez tabelę, sprawdza warunek dla każdego wiersza i zostawia te, dla których jest prawdziwy.

Wracają trzy wiersze: Neuromancer, Hyperion i The Martian. Warunek year > 1980 został sprawdzony dla każdego wiersza i przetrwały tylko te pasujące.

Model myślowy: WHERE to filtr między FROM a wybieranymi kolumnami. Przechodzi przez niego wszystko, co daje prawdę.

Operatory porównania

Podstawy działają tak, jak się spodziewasz:

= oznacza równość, != albo <> oznacza „różne od”, a <, <=, >, >= służą do porównań kolejności. Napisy porównuje się tymi samymi operatorami: author = 'Asimov' pasuje dokładnie, znak po znaku.

Jedna rzecz, o której warto wiedzieć: SQL używa pojedynczych cudzysłowów dla literałów tekstowych. Podwójne cudzysłowy są dla identyfikatorów (nazw kolumn lub tabel). WHERE author = "Asimov" może w SQLite działać z powodów historycznych, ale nie jest przenośne i może po cichu działać źle, gdy „napis” akurat pasuje do nazwy kolumny. Trzymaj się pojedynczych cudzysłowów.

AND, OR i nawiasy

Prawdziwe zapytania zwykle łączą warunki. AND wymaga, żeby obie strony były prawdziwe; OR wymaga co najmniej jednej:

Pierwsze zapytanie wybiera książki nowe i krótkie. Drugie pobiera książki któregokolwiek z dwóch autorów.

Gdy mieszasz AND i OR, kolejność działań daje w kość. AND wiąże silniej niż OR, więc:

czyta się jako Herbert OR (Gibson AND year > 1980): każda książka Herberta niezależnie od roku, plus książki Gibsona po 1980. Pewnie nie o to chodziło. Zapisz swój zamiar w nawiasach:

W razie wątpliwości dodaj nawiasy. Optymalizatorowi zapytań to obojętne, a następna osoba, która to przeczyta, będzie ci wdzięczna.

NULL nie zachowuje się jak wartość

To pułapka klauzuli WHERE, na którą każdy raz się złapie. NULL w SQL oznacza „nieznane”, a nieznanych wartości nie da się porównywać. column = NULL nie jest fałszem: to NULL, które WHERE traktuje jako „pomiń ten wiersz”.

IS NULL i IS NOT NULL to jedyne operatory, które bezpośrednio sprawdzają NULL. Wbij je sobie w palce: każde inne porównanie z NULL zwraca NULL i po cichu odrzuca wiersze.

Ta sama zasada dotyczy negacji. WHERE author != 'Asimov' nie zwraca wierszy, w których author IS NULL, bo NULL != 'Asimov' to też NULL. Jeśli chcesz uwzględnić NULL, poproś o nie jawnie: WHERE author != 'Asimov' OR author IS NULL.

IN i BETWEEN: skróty na co dzień

IN sprawdza przynależność do listy. To czytelniejszy sposób na zapisanie łańcucha OR:

BETWEEN sprawdza zakres, włącznie z oboma końcami:

year BETWEEN 1980 AND 2000 jest identyczne z year >= 1980 AND year <= 2000, tylko krótsze. Pamiętaj: obie granice są włączone. Jeśli chcesz granic wyłącznych, rozpisz porównania.

Krótka uwaga o IN i NULL: WHERE column NOT IN (1, 2, NULL) nigdy nie zwróci żadnego wiersza, bo porównanie czegokolwiek z NULL daje NULL. Usuń NULL z listy albo obsłuż je osobno przez IS NULL.

LIKE do dopasowywania wzorców

LIKE dopasowuje wzorce tekstowe z dwoma symbolami wieloznacznymi:

  • % pasuje do dowolnego ciągu znaków (także pustego).
  • _ pasuje do dokładnie jednego znaku.

Domyślnie LIKE w SQLite nie rozróżnia wielkości liter ASCII: 'Dune' LIKE 'dune' jest prawdą. To zaskakuje osoby przychodzące z Postgresa, gdzie LIKE rozróżnia wielkość liter, a ILIKE to wersja bez rozróżniania. (SQLite nie ma ILIKE.)

Jeśli potrzebujesz dopasowania z rozróżnianiem wielkości liter, masz dwie opcje. Przełącz globalną pragmę:

PRAGMA case_sensitive_like = ON;

Albo użyj GLOB, który zawsze rozróżnia wielkość liter i korzysta z symboli wieloznacznych w stylu Unix (* dla dowolnego ciągu, ? dla jednego znaku):

GLOB 'd*' nie dopasowałby tu niczego: wielkość liter ma znaczenie.

Filtrowanie dat

SQLite przechowuje daty jako tekst (zwykle YYYY-MM-DD albo pełne ISO 8601), więc porównania napisów działają przy okazji jako porównania dat, o ile trzymasz się formatu ISO:

Ponieważ '2024-06-01' < '2024-11-08' jest prawdą zarówno dla napisów, jak i dla dat, te zapytania robią to, czego się spodziewasz. Jeśli przechowujesz daty w innym formacie ('15/01/2024', 'Jan 15 2024'), porównania po cichu dadzą błędne wyniki. Zawsze używaj ISO 8601, a w przyszłości sobie za to podziękujesz.

Do trudniejszych obliczeń na datach (wyciąganie roku, porównanie z „dzisiaj”) SQLite ma funkcje date(), strftime() i julianday(). Omawiamy je w rozdziale o dacie i czasie.

Wszystko razem

Zapytanie, które używa kilku z tych elementów naraz:

Czytaj je linijka po linijce: zostaw wiersze ze znanym rokiem, w zakresie, jednego z dwóch autorów albo wystarczająco długie, i nie szkice. To klauzula WHERE w najlepszym wydaniu: łączy małe, czytelne warunki w precyzyjne filtry.

Dwa nawyki, które warto zachować:

  • Każdy warunek pisz w osobnej linii z wcięciem. Długie klauzule WHERE zapisane w jednej ogromnej linii szybko stają się nieczytelne.
  • Komentuj intencję tam, gdzie warunek nie jest oczywisty. -- pomiń szkice to tanie ubezpieczenie.

Dalej: operatory i NULL w szczegółach

Klauzula WHERE to głównie operatory zastosowane do kolumn, a NULL po cichu zmienia działanie każdego z nich. Następna strona wchodzi głębiej w zestaw operatorów SQLite: arytmetykę, łączenie napisów przez ||, rodzinę IS i logikę trójwartościową, żeby niespodzianki przestały być niespodziankami.

Najczęściej zadawane pytania

Jak działa klauzula WHERE w SQLite?

WHERE filtruje wiersze zapytania, sprawdzając warunek dla każdego wiersza. Wiersze, dla których warunek jest prawdziwy, zostają; te, dla których jest fałszywy albo NULL, są odrzucane. Klauzula stoi zaraz po FROM: SELECT ... FROM table WHERE condition.

Jak połączyć kilka warunków w klauzuli WHERE w SQLite?

Użyj AND i OR. AND wymaga, żeby obie strony były prawdziwe; OR potrzebuje tylko jednej. AND wiąże silniej niż OR, więc mieszane warunki ujmuj w nawiasy, żeby zapis był jednoznaczny: WHERE (a OR b) AND c.

Dlaczego WHERE column = NULL nie działa w SQLite?

NULL oznacza „nieznane”, więc każde porównanie przez = albo != zwraca NULL zamiast prawdy lub fałszu, a wiersze zostają tylko wtedy, gdy warunek jest prawdziwy. Zamiast tego używaj IS NULL i IS NOT NULL. To jedyne operatory, które bezpośrednio sprawdzają NULL.

Czy LIKE w klauzuli WHERE w SQLite rozróżnia wielkość liter?

Domyślnie LIKE nie rozróżnia wielkości liter dla znaków ASCII: 'Hello' LIKE 'hello' jest prawdą. Aby w pełni rozróżniać wielkość liter, ustaw PRAGMA case_sensitive_like = ON; albo użyj GLOB, który zawsze rozróżnia wielkość liter i korzysta z symboli wieloznacznych w stylu Unix (* i ?).

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ