JOIN — Объединение таблиц¶
Оператор JOIN позволяет объединять строки из двух или более таблиц на основе связанного столбца между ними. Это одна из самых мощных возможностей SQL.
📋 Типы JOIN¶
1. INNER JOIN (Внутреннее соединение)¶
Возвращает только те строки, для которых есть совпадение в обеих таблицах.
SELECT employees.name, departments.dept_name
FROM employees
INNER JOIN departments ON employees.dept_id = departments.id;
Пример данных:
| employees | departments | ||
|---|---|---|---|
| id | name | dept_id | id |
| 1 | Иван | 10 | 10 |
| 2 | Мария | 20 | 20 |
| 3 | Петр | 30 | 30 |
Результат:
| name | dept_name |
|---|---|
| Иван | Бухгалтерия |
| Мария | IT |
| Петр | Продажи |
2. LEFT JOIN (Левое соединение)¶
Возвращает все строки из левой таблицы и совпадающие строки из правой. Если совпадений нет, возвращаются NULL.
SELECT employees.name, departments.dept_name
FROM employees
LEFT JOIN departments ON employees.dept_id = departments.id;
Результат (если у сотрудника нет департамента):
| name | dept_name |
|---|---|
| Иван | Бухгалтерия |
| Мария | IT |
| Петр | Продажи |
| Анна | NULL |
3. RIGHT JOIN (Правое соединение)¶
Возвращает все строки из правой таблицы и совпадающие строки из левой.
SELECT employees.name, departments.dept_name
FROM employees
RIGHT JOIN departments ON employees.dept_id = departments.id;
4. FULL OUTER JOIN (Полное внешнее соединение)¶
Возвращает все строки из обеих таблиц. Поддерживается не всеми СУБД (PostgreSQL поддерживает, MySQL — нет).
SELECT employees.name, departments.dept_name
FROM employees
FULL OUTER JOIN departments ON employees.dept_id = departments.id;
5. CROSS JOIN (Декартово произведение)¶
Возвращает декартово произведение всех строк обеих таблиц.
🔗 Условия соединения¶
Соединение по нескольким условиям¶
SELECT e.name, d.dept_name, l.city
FROM employees e
INNER JOIN departments d ON e.dept_id = d.id AND e.active = 1
INNER JOIN locations l ON d.location_id = l.id;
Самосоединение (Self Join)¶
Используется для соединения таблицы с самой собой.
SELECT e1.name AS employee, e2.name AS manager
FROM employees e1
LEFT JOIN employees e2 ON e1.manager_id = e2.id;
⚠️ Частые ошибки¶
| Ошибка | Проблема | Решение |
|---|---|---|
| Забытое условие ON | Возвращается декартово произведение | Всегда указывайте условие JOIN |
| Неправильный тип JOIN | Потеря данных | Выбирайте тип соединения осознанно |
| Дубликаты в результатах | Несколько совпадений | Проверьте уникальность ключей |
| Путаница с NULL | LEFT JOIN может вернуть NULL | Используйте COALESCE для обработки |
💡 Практические примеры¶
Пример 1: Отчёт по продажам¶
SELECT
c.customer_name,
o.order_date,
p.product_name,
oi.quantity,
oi.price
FROM customers c
INNER JOIN orders o ON c.id = o.customer_id
INNER JOIN order_items oi ON o.id = oi.order_id
INNER JOIN products p ON oi.product_id = p.id
ORDER BY o.order_date DESC;
Пример 2: Поиск сотрудников без департамента¶
Пример 3: Подсчёт заказов по клиентам¶
SELECT
c.customer_name,
COUNT(o.id) AS order_count
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.customer_name
ORDER BY order_count DESC;
🎯 Ключевые моменты¶
- INNER JOIN — только совпадающие записи
- LEFT JOIN — все записи слева + совпадения справа
- RIGHT JOIN — все записи справа + совпадения слева
- FULL OUTER JOIN — все записи из обеих таблиц
- Всегда указывайте условие
ONдля соединения - Используйте алиасы таблиц для читаемости
➡️ Что дальше?¶
Изучите агрегатные функции для анализа объединённых данных!