← К оглавлению занятия

Занятие 22. Операторы JOIN и UNION

📁 Блок: SQL / MySQL / Связи и JOIN ⏱️ Время изучения: ~90 мин 🎯 Сложность: Средняя
#select #from #join #union

⚡ Кратко: решения

  • UNION ALL для объединения имён из разных таблиц.
  • INNER/LEFT/RIGHT JOIN с условием ON e.id = ep.employee_id.
  • JOIN products ... GROUP BY product_name для подсчёта заказов.

✅ Решения заданий

Задание 1. UNION: общая выборка имён

USE northwind;

SELECT first_name, last_name
FROM employees
UNION ALL
SELECT first_name, last_name
FROM customers;

Объяснение: UNION ALL сохраняет все строки из обоих запросов. Если бы использовали UNION, совпадающие полные строки удалились бы.

Задание 2. UNION ALL с источником строки

USE northwind;

SELECT first_name, last_name, 'employee' AS status
FROM employees
UNION ALL
SELECT first_name, last_name, 'customer' AS status
FROM customers;

Объяснение: литерал 'employee' добавляет фиксированное значение ко всем строкам первого запроса, 'customer' — ко второму. Количество столбцов в обоих SELECT одинаково: 3.

Задание 3. Сравнение JOIN-ов

USE northwind;

-- Только сотрудники с хотя бы одной привилегией
SELECT *
FROM employees AS e
INNER JOIN employee_privileges AS ep
  ON e.id = ep.employee_id;

-- Все сотрудники; при отсутствии привилегий столбцы ep.* будут NULL
SELECT *
FROM employees AS e
LEFT JOIN employee_privileges AS ep
  ON e.id = ep.employee_id;

-- Все записи employee_privileges; при отсутствии сотрудника столбцы e.* будут NULL
SELECT *
FROM employees AS e
RIGHT JOIN employee_privileges AS ep
  ON e.id = ep.employee_id;

Объяснение: в первом запросе убираются сотрудники без привилегий. Во втором они остаются с NULL. В третьем — остаются все привилегии.

Задание 4. JOIN + подмена идентификатора

USE northwind;

SELECT od.order_id, p.product_name
FROM order_details AS od
INNER JOIN products AS p
  ON od.product_id = p.id;

Объяснение: соединяем таблицы по равенству od.product_id = p.id. В выборке вместо числового идентификатора продукта показываем его название.

Задание 5. JOIN + агрегация

USE northwind;

SELECT p.product_name, COUNT(od.order_id) AS order_count
FROM order_details AS od
INNER JOIN products AS p
  ON od.product_id = p.id
GROUP BY p.product_name;

Объяснение: после соединения группируем по названию продукта и считаем количество связанных заказов. Если в одном заказе продукт встречается несколько раз, он посчитается несколько раз; для уникальных заказов используйте COUNT(DISTINCT od.order_id).

Задание 6. Многотабличный LEFT JOIN

USE northwind;

SELECT od.order_id, p.product_name, po.payment_amount
FROM order_details AS od
LEFT JOIN products AS p
  ON od.product_id = p.id
LEFT JOIN purchase_orders AS po
  ON od.purchase_order_id = po.id;

Объяснение: два последовательных LEFT JOIN сохраняют все строки order_details. Если связанного продукта или закупки нет, соответствующие столбцы заполняются NULL.