INTERSECT: пересечение множеств
Что такое INTERSECT и зачем он нужен? 🔍
INTERSECT в SQL — это оператор, который возвращает только те строки, которые есть в обоих наборах данных. Представьте, что у вас есть два списка:
- Список клиентов, купивших товар в январе
- Список клиентов, купивших товар в феврале
INTERSECT покажет только тех, кто покупал и в январе, и в феврале — это и есть пересечение множеств!
SELECT customer_id FROM january_sales
INTERSECT
SELECT customer_id FROM february_sales;
Как работает INTERSECT под капотом? ⚙️
SQL выполняет три шага:
- Убирает дубликаты в каждом из наборов (как DISTINCT)
- Сравнивает строки между результатами
- Возвращает только совпадающие строки
Важно: количество и порядок столбцов в обоих запросах должны совпадать!
-- Так сработает
SELECT id, name FROM employees
INTERSECT
SELECT id, name FROM contractors;
-- А так вызовет ошибку
SELECT id FROM employees
INTERSECT
SELECT id, name FROM contractors; -- Разное число столбцов!
INTERSECT vs INNER JOIN: в чём разница? 🤔
Хотя оба оператора работают с пересечениями, есть ключевые отличия:
1. INTERSECT:
- Сравнивает все столбцы
- Возвращает только уникальные строки
- Не создаёт декартово произведение
2. INNER JOIN:
- Сравнивает только указанные столбцы
- Может возвращать дубликаты
- Соединяет таблицы по условию
Пример от Данилы:
-- INTERSECT
SELECT product_id FROM winter_catalog
INTERSECT
SELECT product_id FROM summer_catalog;
-- Эквивалент через INNER JOIN
SELECT DISTINCT w.product_id
FROM winter_catalog w
INNER JOIN summer_catalog s ON w.product_id = s.product_id;
Практические примеры из реальной жизни 🛒
Пример 1: Поиск лояльных клиентов
Найдём клиентов, которые делали заказы и в 2022, и в 2023 году:
SELECT customer_id FROM orders_2022
INTERSECT
SELECT customer_id FROM orders_2023;
Пример 2: Общие навыки сотрудников
Определим навыки, которые есть и у разработчиков, и у тестировщиков:
SELECT skill_name FROM developer_skills
INTERSECT
SELECT skill_name FROM qa_skills;
Пример 3: Товары в обоих магазинах
Выведем товары, которые есть и в онлайн, и в офлайн-магазине:
SELECT product_code FROM online_store
INTERSECT
SELECT product_code FROM offline_store;
Важные нюансы при работе с INTERSECT ⚠️
1. Типы данных должны совпадать:
-- Так не сработает, даже если значения выглядят одинаково
SELECT '123' AS text_value
INTERSECT
SELECT 123 AS number_value;
2. NULL-значения считаются равными:
-- Вернёт одну строку с NULL
SELECT NULL
INTERSECT
SELECT NULL;
3. Порядок сортировки не гарантирован — используйте ORDER BY:
SELECT name FROM table1
INTERSECT
SELECT name FROM table2
ORDER BY name DESC;
Альтернативы INTERSECT в разных СУБД 🗃️
Не все базы данных поддерживают INTERSECT напрямую:
1. MySQL — используйте INNER JOIN или EXISTS:
SELECT DISTINCT t1.column
FROM table1 t1
WHERE EXISTS (
SELECT 1 FROM table2 t2
WHERE t2.column = t1.column
);
2. SQLite — поддерживает INTERSECT полностью.
3. PostgreSQL — поддерживает INTERSECT ALL для сохранения дубликатов:
SELECT * FROM table1
INTERSECT ALL
SELECT * FROM table2;
Упражнения для закрепления 🏋️
- Напишите запрос, который найдёт студентов, посещавших и лекции, и практические занятия.
- Сравните производительность INTERSECT и INNER JOIN на вашей базе данных.
- Найдите общие города между поставщиками и клиентами, используя INTERSECT.