Занятие 22. Операторы JOIN и UNION
⚡ Кратко: суть темы
JOIN соединяет таблицы по ключу, UNION складывает строки из разных запросов.
INNER JOIN— только совпадения;LEFT JOIN— всё слева + совпадения справа.UNIONудаляет дубликаты,UNION ALL— нет.- У
UNIONдолжно совпадать число столбцов и типы.
📖 Горизонтальное объединение: UNION и UNION ALL
Операторы UNION и UNION ALL объединяют результаты двух и более SELECT-запросов в один результирующий набор. Строки первого запроса идут первыми, затем строки второго — и так далее.
UNION
- Удаляет полные дубликаты строк.
- Требует больше памяти и времени, чем
UNION ALL, потому что сравнивает строки между наборами.
SELECT column1, column2 FROM table1
UNION
SELECT column1, column2 FROM table2;
UNION ALL
- Сохраняет все строки, включая дубликаты.
- Работает быстрее, когда дубликаты заведомо невозможны или не важны.
SELECT name, email FROM customers
UNION ALL
SELECT name, email FROM employees;
Требования к UNION
- Все
SELECTдолжны возвращать одинаковое количество столбцов. - Соответствующие столбцы должны иметь совместимые типы данных.
- Имена столбцов в итоговой выборке берутся из первого
SELECT.
Проверить по документации: в некоторых СУБД для совместимости типов применяется неявное приведение. Перед промышленным использованием уточняйте правила в документации конкретной базы.
📖 Виды соединений JOIN
JOIN объединяет строки из двух или более таблиц на основе логической связи — обычно равенства значений внешнего и первичного ключей.
| Оператор | Что возвращает | Когда использовать |
|---|---|---|
INNER JOIN |
Только строки, имеющие совпадения в обеих таблицах. | Нужны только связанные данные, без «пустых» строк. |
LEFT JOIN / LEFT OUTER JOIN |
Все строки левой таблицы + совпадающие строки правой. Если совпадений нет — NULL. |
Нужно сохранить все строки основной таблицы, даже без связей. |
RIGHT JOIN |
Все строки правой таблицы + совпадающие строки левой. Если совпадений нет — NULL. |
Редко используется: обычно заменяется LEFT JOIN с перестановкой таблиц. |
CROSS JOIN |
Декартово произведение: каждая строка первой таблицы соединяется с каждой строкой второй. | Почти никогда в продакшене из-за огромного результата. |
FULL JOIN / FULL OUTER JOIN |
Все строки обеих таблиц, NULL там, где нет совпадений. |
Не реализован в MySQL; доступен в PostgreSQL, SQLite и других. |
Визуальная аналогия
- INNER JOIN — пересечение двух множеств.
- LEFT JOIN — всё левое множество + пересечение.
- RIGHT JOIN — всё правое множество + пересечение.
- FULL JOIN — объединение двух множеств.
- CROSS JOIN — все возможные пары элементов.
📖 Общий синтаксис JOIN
SELECT столбцы
FROM таблица1
INNER JOIN таблица2
ON таблица1.колонка = таблица2.колонка;
таблица1итаблица2— таблицы, которые нужно соединить.ON— условие связи. Чаще всего это равенство внешнего ключа одной таблицы первичному ключу другой.- Алиасы (
AS) делают запрос короче и читабельнее.
SELECT o.id, c.company_name
FROM orders AS o
INNER JOIN customers AS c
ON o.customer_id = c.id;
Проверить по документации: в MySQL ключевое слово
INNER можно опускать: JOIN по умолчанию работает как INNER JOIN. В других СУБД поведение может отличаться.
📖 Соединение более двух таблиц
Если данные разбросаны по трём и более таблицах, можно последовательно добавлять JOIN:
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;
Порядок соединений важен: результат каждого предыдущего JOIN становится «левой» таблицей для следующего.
📖 Примеры на схеме northwind
База northwind используется в занятии для демонстрации. Ключевые таблицы:
customers— клиенты (id— первичный ключ).employees— сотрудники (id— первичный ключ).orders— заказы (customer_idссылается наcustomers,employee_id— наemployees).order_details— строки заказов (order_id,product_id).products— товары (id— первичный ключ).purchase_orders— закупки (id— первичный ключ).invoices— инвойсы (order_idссылается наorders).
✨ Современные практики
- Всегда указывайте
ONявно. Неявное соединение через запятую вWHEREустарело и легко приводит к декартову произведению. - Выбирайте минимально необходимый тип JOIN: если нужны только связанные строки —
INNER JOIN, неLEFT JOIN. - Используйте
UNION ALL, если дубликаты заведомо невозможны: это быстрее и менее ресурсоёмко. - Проверяйте индексы на столбцах условий
JOIN: без индекса большие таблицы соединяются очень медленно.