0Pricing
SQL Interview Prep · Lekcja

BETWEEN, IN i granice włączne

Przypadki brzegowe oraz sposób, w jaki BETWEEN traktuje końce zakresu

BETWEEN, IN i granice włączne to bezpłatna lekcja SQL Interview Prep na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej SQL Interview Prep, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs SQL Interview Prep zawiera 4 lekcji w sumie.

Dlaczego granice odbierają kandydatom punkty

Filtry zakresów i zbiorów wyglądają banalnie, dlatego rekruterzy wykorzystują przypadki brzegowe. Operator BETWEEN obejmuje oba końce zakresu, IN skrywa subtelną pułapkę z NULL, a zakresy dat są miejscem, w którym błędy przesunięcia o jeden po cichu zniekształcają raporty.

W tej lekcji dokładnie omówiono sposób traktowania końców zakresu przez BETWEEN, sytuacje, w których IN jest czytelniejszy niż łańcuch operatorów OR, oraz wzorzec przedziału półotwartego używany przez profesjonalistów dla dat.

BETWEEN obejmuje oba końce

col BETWEEN a AND b jest skrótem zapisu col >= a AND col <= b. Oba końce zakresu są uwzględniane.

Zatem price BETWEEN 10 AND 20 zwraca również wiersze, w których cena wynosi dokładnie 10 lub dokładnie 20, a także wszystkie wartości pomiędzy nimi. Najczęstszą błędną odpowiedzią na rozmowach kwalifikacyjnych jest stwierdzenie, że górna granica nie jest uwzględniana.

SELECT *
FROM products
WHERE price BETWEEN 10 AND 20;
-- equivalent to: price >= 10 AND price <= 20

Kolejność argumentów ma znaczenie

Operator BETWEEN wymaga podania najpierw mniejszej wartości. col BETWEEN 20 AND 10 rozwija się do col >= 20 AND col <= 10, co nigdy nie może być prawdą, dlatego zapytanie zwraca zero wierszy, a nie błąd.

To ulubiona pułapka rekruterów: zapytanie wykonuje się bez problemu, nic nie zwraca, a kandydat zakłada, że baza jest pusta. Zawsze należy podawać mniejszą granicę jako pierwszą.

SELECT *
FROM products
WHERE price BETWEEN 20 AND 10;
-- returns NOTHING, not an error

Błąd o jeden w zakresie dat

Poproszeni o cały styczeń kandydaci często piszą order_date BETWEEN '2024-01-01' AND '2024-01-31'. Jeśli order_date jest znacznikiem czasu, takie zapytanie pomija wszystko po północy 31 stycznia, ponieważ 2024-01-31 oznacza 2024-01-31 00:00:00.

Zamówienie złożone 31 stycznia o godzinie 14:00 zostanie pominięte. W przypadku kolumn typu DATE to działa, ale nie można zakładać, jaki jest typ kolumny.

SELECT *
FROM orders
WHERE order_date BETWEEN '2024-01-01' AND '2024-01-31';
-- silently excludes Jan 31 afternoon if order_date is a timestamp

Rozwiązanie: przedział półotwarty

Profesjonalny wzorzec dla dat to przedział półotwarty: wartość większa lub równa początkowi oraz ściśle mniejsza od początku następnego okresu. Jest poprawny zarówno dla DATE, jak i TIMESTAMP, a ponadto nie wymaga znajomości rozdzielczości czasowej kolumny.

Proszę zauważyć, że górną granicą jest pierwszy dzień lutego, a nie ostatni dzień stycznia. Dzięki temu uwzględniona zostaje każda chwila stycznia.

SELECT *
FROM orders
WHERE order_date >= '2024-01-01'
  AND order_date <  '2024-02-01';

NOT BETWEEN

col NOT BETWEEN a AND b rozwija się do col < a OR col > b. Wyklucza oba końce zakresu oraz wszystko pomiędzy nimi.

Uwaga: jeśli col ma wartość NULL, wyrażenie NOT BETWEEN przyjmuje wartość UNKNOWN, dlatego wiersze z wartością NULL są wykluczane tak samo jak w przypadku zwykłego BETWEEN. Wartości NULL nigdy nie spełniają testu zakresu w żadnym kierunku.

SELECT *
FROM products
WHERE price NOT BETWEEN 10 AND 20;
-- price < 10 OR price > 20

IN jako przynależność do zbioru

col IN (a, b, c) jest skrótem zapisu col = a OR col = b OR col = c. To czytelny sposób sprawdzania przynależności do małego, z góry określonego zbioru.

Taki zapis jest czytelniejszy niż łańcuch operatorów OR i całkowicie eliminuje problem dodawania nawiasów wynikający z pierwszeństwa operatorów, ponieważ test całego zbioru stanowi jeden predykat.

SELECT *
FROM orders
WHERE status IN ('pending', 'shipped', 'delivered');

Pułapka NULL w NOT IN

To najbardziej obawiane pytanie dotyczące IN. Jeśli lista lub podzapytanie używane przez NOT IN zawiera choć jedną wartość NULL, całe wyrażenie może przyjąć wartość UNKNOWN i zwrócić zero wierszy.

Powód jest następujący: x NOT IN (1, NULL) staje się x <> 1 AND x <> NULL, a x <> NULL nigdy nie jest prawdą — ma wartość UNKNOWN. Całe wyrażenie AND nie może więc być prawdziwe.

SELECT *
FROM employees
WHERE manager_id NOT IN (SELECT id FROM managers);
-- returns NOTHING if any managers.id is NULL

Naprawianie NOT IN

Dwa niezawodne sposoby rozwiązania pułapki NULL w NOT IN:

  • odfiltrować wartości NULL z podzapytania za pomocą WHERE id IS NOT NULL
  • jeszcze lepiej — przepisać zapytanie z użyciem NOT EXISTS, który z założenia poprawnie obsługuje wartości NULL

Rekruterzy uznają NOT EXISTS za odpowiedź świadczącą o doświadczeniu, ponieważ całkowicie omija tę pułapkę i często pozwala uzyskać lepszy plan wykonania.

SELECT e.*
FROM employees e
WHERE NOT EXISTS (
  SELECT 1 FROM managers m WHERE m.id = e.manager_id
);

IN z podzapytaniem

IN przyjmuje podzapytanie zwracające jedną kolumnę. WHERE customer_id IN (SELECT customer_id FROM vip) zachowuje wiersze, których klient znajduje się w zbiorze VIP.

Zwykły IN — w przeciwieństwie do NOT IN — jest bezpieczny, gdy podzapytanie zawiera wartości NULL: wartość NULL na liście po prostu nigdy nie pasuje, ale nie wpływa na wiersze, które pasują. Pułapka dotyczy konkretnie operatora NOT IN.

SELECT *
FROM orders
WHERE customer_id IN (SELECT customer_id FROM vip_customers);

IN dla wielu kolumn za pomocą konstruktorów wierszy

Częste pytanie dodatkowe brzmi: jak dopasować więcej niż jedną kolumnę naraz? Należy przekazać krotkę do IN za pomocą konstruktora wiersza — porównuje on kolumny pozycyjnie i jest znacznie bardziej przejrzysty niż łączenie wielu warunków OR (a = .. AND b = ..).

  • Takie rozwiązanie jest czytelne i dobrze skaluje się do długich list dozwolonych wartości.
  • Każda krotka musi zawierać kolumny w tej samej kolejności.
SELECT *
FROM orders
WHERE (customer_id, status) IN ((101, 'paid'), (102, 'shipped'));

Szybki test

Proszę przypomnieć sobie, jak operator BETWEEN traktuje końce zakresu.

Podsumowanie

Najważniejsze wnioski:

  • BETWEEN a AND b uwzględnia oba końce zakresu; mniejsza granica musi wystąpić pierwsza, w przeciwnym razie otrzymuje się zero wierszy
  • W zakresach znaczników czasu należy używać przedziału półotwartego: >= start AND < next_period
  • IN w czytelny sposób sprawdza przynależność do zbioru i jest bezpieczny dla wartości NULL
  • NOT IN z dowolną wartością NULL na liście nic nie zwraca; należy przepisać je jako NOT EXISTS

Powtarzający się motyw jest następujący: filtr może wykonać się bezbłędnie, a mimo to po cichu zwrócić niewłaściwe wiersze.

Często zadawane pytania

Czy lekcja „BETWEEN, IN i granice włączne” jest bezpłatna?

Tak — pełny tekst „BETWEEN, IN i granice włączne” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu SQL Interview Prep, przejdź na CoddyKit PRO. Kurs SQL Interview Prep zawiera 4 lekcji w sumie.

Co nauczysz się w „BETWEEN, IN i granice włączne”?

Przypadki brzegowe oraz sposób, w jaki BETWEEN traktuje końce zakresu Ćwiczysz SQL Interview Prep z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć SQL Interview Prep?

Nie wymagamy żadnego doświadczenia. SQL Interview Prep w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „BETWEEN, IN i granice włączne”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji SQL Interview Prep?

Tak. Każda lekcja SQL Interview Prep zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Pierwszeństwo AND/OR i używanie nawiasów
  2. BETWEEN, IN i granice włączne
  3. LIKE, symbole wieloznaczne i znaki ucieczki
  4. Filtrowanie według wartości obliczanych
← Powrót do SQL Interview Prep