Читать книгу SQL для аналитика. 50 задач с решениями на PostgreSQL - Ар'лан ис'Дрекхэм - Страница 7
Часть 1. Установка. Повторение SQL
Глава 5. Повторяем UNION, INTERSECT, EXCEPT
ОглавлениеОписание задачи
Повторим операторы, которые работают с множествами, используют результат двух и более запросов: UNION, INTERSECT, EXCEPT.
Эти команды могут объединять, пересекать и вычитать наборы строк.
Это особенно удобно, когда нужно сравнить два набора данных в одном отчёте или, наоборот, убрать лишние данные, или же найти данные, которые есть и в одном, и в другом наборе.
Такие задачи очень часто встречаются в работе аналитика.
Основные SQL-конструкции
UNION – объединяет результаты двух запросов, убирая дубликаты.
UNION ALL – объединяет результаты, оставляя дубликаты.
INTERSECT – возвращает строки, которые есть в обоих запросах.
EXCEPT – возвращает строки из первого запроса, которых нет во втором.
Важные требования:
– Количество колонок в запросах должно совпадать.
– Типы данных колонок должны быть совместимы.
– Порядок колонок имеет значение.
Примеры:
– UNION: пользователи, которые сделали заказы ИЛИ оставили отзывы.
– INTERSECT: пользователи, которые сделали заказы И оставили отзывы.
– EXCEPT: пользователи, которые сделали заказы, НО не оставили отзывы.
Совет
UNION убирает дубликаты и сортирует результат. Сначала объединяет данные, потом убирает дубли. Если это не важно, используйте UNION ALL – он будет работать быстрее.
Представьте, вам нужен отчёт: посмотреть заказы из Москвы и Казани. Используем UNION.
Отдельно выбираем заказы пользователей из Москвы, отдельно из Казани, объединяем.
text
SELECT o. order_id, o. order_date, u.user_name, u.city
FROM orders o
JOIN users u ON o.user_id = u.user_id
WHERE u.city = «Москва»/*фильр Мсоква*/
UNION
SELECT o. order_id, o. order_date, u.user_name, u.city
FROM orders o
JOIN users u ON o.user_id = u.user_id
WHERE u.city = «Казань» ORDER BY order_date;
Как это работает
– Первый запрос – заказы пользователей из Москвы.
– Второй запрос – заказы пользователей из Казани.
– UNION объединяет результаты и убирает дубликаты (если пользователь из Москвы сделал заказ и как-то попал в Казань – но такого не будет).
– ORDER BY применяется к общему результату.
Пример вывода (фрагмент):
order_id 3, order_date 2024-01-10, user_name alex_ivanov, city Москва
order_id 7, order_date 2024-01-25, user_name ivan_sokolov, city Казань
SQL-запросы с объяснением
Задача 1. Пользователи, которые и покупали, и оставляли отзывы (INTERSECT).
text
SELECT user_id FROM orders
INTERSECT
SELECT user_id FROM user_comments;
Как это работает
– Первый запрос – все user_id из заказов.
– Второй запрос – все user_id из отзывов.
– INTERSECT оставляет только тех, кто есть в обоих списках.
Типичная ошибка
INTERSECT требует совпадения по всем колонкам. Если добавить в SELECT лишнюю колонку (например, order_date), результат может стать пустым, потому что дата заказа не совпадёт с датой отзыва.
Задача 2. Пользователи, которые покупали, но не оставляли отзывы (EXCEPT).
text
SELECT user_id FROM orders
EXCEPT
SELECT user_id FROM user_comments;
Как это работает
– Первый запрос – все user_id из заказов.
– Второй запрос – все user_id из отзывов.
– EXCEPT убирает из первого списка тех, кто есть во втором.
Задача 3. Сравнение двух способов: UNION vs UNION ALL.
text
SELECT country FROM users
WHERE country = «Россия» UNION
SELECT country FROM users WHERE country = «Россия»;
Вернёт одну строку: «Россия».
text
SELECT country FROM users WHERE country = «Россия»/*1*/
UNION ALL
SELECT country FROM users WHERE country = «Россия»;
Вернёт столько строк, сколько пользователей из России (каждый дубль сохранится).
Вопросы и ответы
В: Чем UNION отличается от UNION ALL?
О: UNION убирает дубликаты и сортирует результат. UNION ALL оставляет все строки как есть и работает быстрее.
В: Какой порядок выполнения у UNION, INTERSECT, EXCEPT?
О: Все операторы имеют одинаковый приоритет. Для управления порядком используйте скобки.
В: Можно ли комбинировать больше двух запросов?
О: Да. SELECT… UNION SELECT… INTERSECT SELECT … – но лучше использовать скобки, чтобы явно задать порядок.
Что в итоге
Мы научились:
– Объединять результаты запросов с UNION и UNION ALL.
– Находить пересечения с INTERSECT.
– Вычитать множества с EXCEPT.
То есть освоили все команды работы с множествами.
Эти операторы удобны для сравнения списков и подготовки отчётов.
* Задание со звёздочкой
Напишите запрос, который выводит user_id пользователей, которые оставляли отзывы, но никогда не покупали товары из категории «Смартфоны».
Используйте EXCEPT и подзапрос с JOIN.