Уяви, що ти працюєш у базі даних університету і тобі треба знайти студентів, які навчаються на конкретних курсах. Наприклад, на "Програмуванні", "Математиці" та "Фізиці". Звісно, ти можеш написати довгий запит з купою умов типу:
SELECT *
FROM students
WHERE course = 'Програмування'
OR course = 'Математика'
OR course = 'Фізика';
Але давай чесно. Писати такі конструкції нудно і виглядають вони не дуже елегантно. На щастя, на допомогу приходить оператор IN, який дозволяє записати той самий запит компактно і зекономити час:
SELECT *
FROM students
WHERE course IN ('Програмування', 'Математика', 'Фізика');
Звучить як магія, правда? Замість купи умов OR ми просто кажемо SQL шукати значення у цьому списку. А якщо треба перевірити, що значення не входить у список, використовуємо NOT IN — Шукати все, чого нема у цьому списку.
Синтаксис оператора IN
Ось загальний синтаксис оператора IN:
SELECT колонки
FROM таблиця
WHERE колонка IN (значення1, значення2, значення3, ...);
Тепер давай розглянемо кілька прикладів.
Приклад 1: Студенти, які вивчають кілька курсів
Припустимо, у нас є таблиця students:
| id | name | course |
|---|---|---|
| 1 | Anna | Програмування |
| 2 | Mello | Фізика |
| 3 | Kate | Математика |
| 4 | Dan | Хімія |
| 5 | Olly | Біологія |
Ми хочемо знайти всіх студентів, які вивчають "Програмування", "Математику" або "Фізику". Використовуємо IN:
SELECT name, course
FROM students
WHERE course IN ('Програмування', 'Математика', 'Фізика');
Результат:
| name | course |
|---|---|
| Anna | Програмування |
| Mello | Фізика |
| Kate | Математика |
Як бачиш, оператор IN значно спростив задачу. Нам не треба писати довгі умови через OR, просто вказуємо список значень, які нас цікавлять.
Приклад 2: Студенти, які не вивчають певні курси
Тепер, уяви, що ти хочеш знайти студентів, які не вивчають "Програмування", "Математику" і "Фізику". Для цього стане у пригоді оператор NOT IN:
SELECT name, course
FROM students
WHERE course NOT IN ('Програмування', 'Математика', 'Фізика');
Результат:
| name | course |
|---|---|
| Dan | Хімія |
| Olly | Біологія |
Таким чином, оператор NOT IN повертає всі рядки, де значення стовпця course не входять у вказаний список.
Використання IN та NOT IN з підзапитами
Оператори IN та NOT IN особливо корисні, коли треба порівняти дані між двома таблицями. Наприклад, нехай у нас є дві таблиці:
Таблиця students:
| id | name | course_id |
|---|---|---|
| 1 | Anna | 101 |
| 2 | Mello | 102 |
| 3 | Kate | 103 |
| 4 | Dan | 104 |
Таблиця courses:
| id | name |
|---|---|
| 101 | Програмування |
| 102 | Фізика |
| 103 | Математика |
| 105 | Хімія |
Уявімо, що нам треба знайти студентів, які зареєстровані на курси, що існують у таблиці courses. Тут на допомогу приходить вкладений запит з використанням IN:
SELECT name
FROM students
WHERE course_id IN (
SELECT id
FROM courses
);
Цей запит працює так: підзапит SELECT id FROM courses повертає список усіх ідентифікаторів курсів. Далі оператор IN перевіряє, чи є course_id у цьому списку.
Результат:
| name |
|---|
| Anna |
| Mello |
| Kate |
Чому пропущено Dan? Бо його course_id (104) відсутній у таблиці courses.
Особливості роботи з NULL
Оператор IN має одну важливу особливість: якщо у списку значень зустрічається NULL, це може вплинути на результат запиту. Давай розглянемо приклад.
Таблиця grades:
| student_id | course_id | grade |
|---|---|---|
| 1 | 101 | A |
| 2 | 102 | NULL |
| 3 | 103 | B |
Запит, який шукає студентів з оцінкою в ('A', 'B', 'C'), може виглядати так:
SELECT student_id
FROM grades
WHERE grade IN ('A', 'B', 'C');
Результат:
| student_id |
|---|
| 1 |
| 3 |
Запис з NULL у стовпці grade ігнорується, бо NULL не вважається частиною жодного списку.
Тепер уяви, що ти використовуєш оператор NOT IN. Наприклад:
SELECT student_id
FROM grades
WHERE grade NOT IN ('A', 'B', 'C');
Ти очікуєш побачити рядок з student_id = 2, але результат буде порожній! Чому? Бо NULL порівнюється з кожним значенням у списку, і результат такого порівняння завжди невизначений (UNKNOWN). Це може збити з пантелику, тому працюючи з NOT IN, треба враховувати наявність стовпців з NULL. Краще явно перевірити NULL при використанні NOT IN:
SELECT student_id
FROM grades
WHERE grade NOT IN ('A', 'B', 'C')
OR grade IS NULL;
Результат:
| student_id |
|---|
| 2 |
Поради щодо використання IN та NOT IN
Використовуй IN для покращення читабельності твого SQL-коду
Якщо треба перевірити, чи входить стовпець у певний список значень, завжди віддавай перевагу IN, а не купі умов з OR.
Будь обережний з NOT IN та NULL
Якщо у даних є стовпці з NULL, вони можуть викликати неочікувані результати. Краще явно обробити NULL при використанні NOT IN.
Використовуй індекси для прискорення підзапитів
Якщо IN використовується з вкладеним запитом, переконайся, що стовпець у підзапиті проіндексований, щоб уникнути проблем з продуктивністю.
Приклад реального завдання
Уяви, що ти працюєш у системі інтернет-магазину. У тебе є таблиці orders та users. Ти хочеш знайти всіх користувачів, які ніколи не робили замовлення.
Таблиця users:
| id | name |
|---|---|
| 1 | Anna |
| 2 | Mello |
| 3 | Kate |
| 4 | Dan |
Таблиця orders:
| id | user_id | total |
|---|---|---|
| 1 | 1 | 500 |
| 2 | 3 | 300 |
Використовуємо NOT IN для вирішення задачі:
SELECT name
FROM users
WHERE id NOT IN (
SELECT user_id
FROM orders
);
Результат:
| name |
|---|
| Mello |
| Dan |
Цей запит працює так: спочатку підзапит SELECT user_id FROM orders повертає ідентифікатори всіх користувачів, які робили замовлення (1 і 3). Далі оператор NOT IN виключає їх, залишаючи тільки тих, хто не робив замовлень (Mello і Dan).
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ