Wyobraź sobie, że pracujesz na bazie danych uniwersytetu i musisz znaleźć studentów, którzy uczą się na konkretnych kursach. Na przykład na "Programowaniu", "Matematyce" i "Fizyce". Jasne, możesz napisać długie zapytanie z wieloma warunkami typu:
SELECT *
FROM students
WHERE course = 'Programowanie'
OR course = 'Matematyka'
OR course = 'Fizyka';
Ale bądźmy szczerzy. Pisanie takich konstrukcji jest męczące i nie wygląda zbyt elegancko. Na szczęście z pomocą przychodzi operator IN, który pozwala zapisać to samo zapytanie w skrócie i zaoszczędzić czas:
SELECT *
FROM students
WHERE course IN ('Programowanie', 'Matematyka', 'Fizyka');
Brzmi jak magia, prawda? Zamiast wielu warunków OR po prostu mówimy SQL-owi, żeby szukał wartości z tej listy. A jeśli chcesz sprawdzić, że wartość nie znajduje się na liście, używasz NOT IN — Szukaj wszystkiego, czego nie ma na tej liście.
Składnia operatora IN
Oto ogólna składnia operatora IN:
SELECT kolumny
FROM tabela
WHERE kolumna IN (wartosc1, wartosc2, wartosc3, ...);
Teraz zobaczmy kilka przykładów.
Przykład 1: Studenci uczący się kilku kursów
Załóżmy, że mamy tabelę students:
| id | name | course |
|---|---|---|
| 1 | Anna | Programowanie |
| 2 | Mello | Fizyka |
| 3 | Kate | Matematyka |
| 4 | Dan | Chemia |
| 5 | Olly | Biologia |
Chcemy znaleźć wszystkich studentów, którzy uczą się "Programowania", "Matematyki" lub "Fizyki". Używamy IN:
SELECT name, course
FROM students
WHERE course IN ('Programowanie', 'Matematyka', 'Fizyka');
Wynik:
| name | course |
|---|---|
| Anna | Programowanie |
| Mello | Fizyka |
| Kate | Matematyka |
Jak widzisz, operator IN mocno uprościł sprawę. Nie musimy pisać długich warunków z OR, po prostu podajemy listę wartości, które nas interesują.
Przykład 2: Studenci, którzy nie uczą się wybranych kursów
Teraz załóżmy, że chcesz znaleźć studentów, którzy nie uczą się "Programowania", "Matematyki" i "Fizyki". Do tego przyda się operator NOT IN:
SELECT name, course
FROM students
WHERE course NOT IN ('Programowanie', 'Matematyka', 'Fizyka');
Wynik:
| name | course |
|---|---|
| Dan | Chemia |
| Olly | Biologia |
Tak więc operator NOT IN zwraca wszystkie wiersze, gdzie wartości kolumny course nie znajdują się na podanej liście.
Użycie IN i NOT IN z podzapytaniami
Operatory IN i NOT IN są szczególnie przydatne, gdy trzeba porównać dane między dwiema tabelami. Na przykład, mamy dwie tabele:
Tabela students:
| id | name | course_id |
|---|---|---|
| 1 | Anna | 101 |
| 2 | Mello | 102 |
| 3 | Kate | 103 |
| 4 | Dan | 104 |
Tabela courses:
| id | name |
|---|---|
| 101 | Programowanie |
| 102 | Fizyka |
| 103 | Matematyka |
| 105 | Chemia |
Załóżmy, że musimy znaleźć studentów zapisanych na kursy, które istnieją w tabeli courses. Tutaj przyda się podzapytanie z użyciem IN:
SELECT name
FROM students
WHERE course_id IN (
SELECT id
FROM courses
);
To zapytanie działa tak: podzapytanie SELECT id FROM courses zwraca listę wszystkich identyfikatorów kursów. Potem operator IN sprawdza, czy course_id jest na tej liście.
Wynik:
| name |
|---|
| Anna |
| Mello |
| Kate |
Dlaczego Dan został pominięty? Bo jego course_id (104) nie ma w tabeli courses.
Specyfika pracy z NULL
Operator IN ma jedną ważną cechę: jeśli na liście wartości pojawi się NULL, może to wpłynąć na wynik zapytania. Zobaczmy przykład.
Tabela grades:
| student_id | course_id | grade |
|---|---|---|
| 1 | 101 | A |
| 2 | 102 | NULL |
| 3 | 103 | B |
Zapytanie, które szuka studentów z oceną w ('A', 'B', 'C'), może wyglądać tak:
SELECT student_id
FROM grades
WHERE grade IN ('A', 'B', 'C');
Wynik:
| student_id |
|---|
| 1 |
| 3 |
Wiersz z NULL w kolumnie grade jest ignorowany, bo NULL nie jest traktowany jako część żadnej listy.
Teraz wyobraź sobie, że używasz operatora NOT IN. Na przykład:
SELECT student_id
FROM grades
WHERE grade NOT IN ('A', 'B', 'C');
Spodziewasz się zobaczyć wiersz z student_id = 2, ale wynik będzie pusty! Dlaczego? Bo NULL porównuje się z każdą wartością z listy i wynik takiego porównania jest zawsze nieokreślony (UNKNOWN). To może być mylące, więc pracując z NOT IN, trzeba brać pod uwagę obecność kolumn z NULL. Najlepiej wtedy dodać jawne sprawdzenie NULL:
SELECT student_id
FROM grades
WHERE grade NOT IN ('A', 'B', 'C')
OR grade IS NULL;
Wynik:
| student_id |
|---|
| 2 |
Wskazówki dotyczące użycia IN i NOT IN
Używaj IN dla lepszej czytelności twojego SQL-kodu
Jeśli musisz sprawdzić, czy kolumna jest na liście wartości, zawsze wybieraj IN zamiast wielu warunków z OR.
Uważaj na NOT IN i NULL
Jeśli w danych są kolumny z NULL, mogą one powodować nieoczekiwane wyniki. Lepiej jawnie obsłużyć NULL przy użyciu NOT IN.
Używaj indeksów do przyspieszenia podzapytań
Jeśli IN jest używany z podzapytaniem, upewnij się, że kolumna w podzapytaniu jest zindeksowana, żeby uniknąć problemów z wydajnością.
Przykład z życia
Wyobraź sobie, że pracujesz w systemie sklepu internetowego. Masz tabele orders i users. Chcesz znaleźć wszystkich użytkowników, którzy nigdy nie złożyli zamówienia.
Tabela users:
| id | name |
|---|---|
| 1 | Anna |
| 2 | Mello |
| 3 | Kate |
| 4 | Dan |
Tabela orders:
| id | user_id | total |
|---|---|---|
| 1 | 1 | 500 |
| 2 | 3 | 300 |
Użyjemy NOT IN do rozwiązania zadania:
SELECT name
FROM users
WHERE id NOT IN (
SELECT user_id
FROM orders
);
Wynik:
| name |
|---|
| Mello |
| Dan |
To zapytanie działa tak: najpierw podzapytanie SELECT user_id FROM orders zwraca identyfikatory wszystkich użytkowników, którzy złożyli zamówienia (1 i 3). Potem operator NOT IN wyklucza ich, zostawiając tylko tych, którzy nie złożyli zamówień (Mello i Dan).
GO TO FULL VERSION