Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Виды JOIN в SQL
Основные четыре типа
JOIN объединяет данные из двух таблиц на основе общего столбца. Различаются тем, какие строки попадают в результат.
1. INNER JOIN (Внутреннее соединение)
Суть: возвращает только строки, которые есть в обеих таблицах.
SELECT users.name, orders.order_id
FROM users
INNER JOIN orders ON users.id = orders.user_id;
| user_id | name | order_id | user_id | |
|---|---|---|---|---|
| 1 | Alice | 101 | 1 | |
| 2 | Bob | 102 | 1 | |
| 3 | Charlie | 103 | 2 |
Результат: только Alice и Bob (у них есть заказы)
name | order_id
--------|----------
Alice | 101
Alice | 102
Bob | 103
2. LEFT JOIN (Левое внешнее соединение)
Суть: возвращает все строки из левой таблицы + совпадающие из правой.
SELECT users.name, orders.order_id
FROM users
LEFT JOIN orders ON users.id = orders.user_id;
Результат: Alice, Bob, Charlie (все, даже без заказов)
name | order_id
--------|----------
Alice | 101
Alice | 102
Bob | 103
Charlie | NULL
3. RIGHT JOIN (Правое внешнее соединение)
Суть: возвращает все строки из правой таблицы + совпадающие из левой.
SELECT users.name, orders.order_id
FROM users
RIGHT JOIN orders ON users.id = orders.user_id;
Результат: все заказы (даже если пользователь удален)
name | order_id
------|----------
Alice | 101
Alice | 102
Bob | 103
4. FULL OUTER JOIN (Полное внешнее соединение)
Суть: возвращает все строки из обеих таблиц.
SELECT users.name, orders.order_id
FROM users
FULL OUTER JOIN orders ON users.id = orders.user_id;
Результат: все пользователи И все заказы
name | order_id
--------|----------
Alice | 101
Alice | 102
Bob | 103
Charlie | NULL
Визуально (диаграммы Венна)
INNER JOIN: LEFT JOIN: RIGHT JOIN: FULL OUTER:
┌───┐ ┌───┐ ┌───┐ ┌───┐
│ A ├─ B │ A ├─ B │ A ├─ B │ A ├─ B
└───┘ └───┘ └───┘ └───┘
пересечение левая таблица правая таблица обе полностью
Практические примеры
-- LEFT JOIN: все товары и их продажи (даже если не продали)
SELECT products.name, COUNT(sales.id) as sold
FROM products
LEFT JOIN sales ON products.id = sales.product_id
GROUP BY products.id;
-- INNER JOIN: только проданные товары
SELECT products.name, COUNT(sales.id) as sold
FROM products
INNER JOIN sales ON products.id = sales.product_id
GROUP BY products.id;
-- FULL OUTER: все данные, сопоставленные или нет (находить несоответствия)
SELECT *
FROM table_a
FULL OUTER JOIN table_b ON table_a.id = table_b.id
WHERE table_a.id IS NULL OR table_b.id IS NULL; -- только несовпадения
Дополнительные типы
CROSS JOIN (Декартово произведение)
-- Комбинирует КАЖДУЮ строку первой с КАЖДОЙ второй
SELECT *
FROM colors
CROSS JOIN sizes;
-- Если colors = 3 строки, sizes = 4 строки → результат 3*4 = 12 строк
SELF JOIN (Соединение таблицы с самой собой)
-- Найти пары сотрудников, работающих в одном отделе
SELECT e1.name, e2.name, e1.department
FROM employees e1
INNER JOIN employees e2
ON e1.department = e2.department
AND e1.id < e2.id; -- избегаем дублей и (Alice, Alice)
Таблица сравнения
| JOIN | Левая | Правая | Результат |
|---|---|---|---|
| INNER | Совпадающие | Совпадающие | Только совпадения |
| LEFT | Все | Совпадающие | Все левая + совпадения |
| RIGHT | Совпадающие | Все | Все правая + совпадения |
| FULL OUTER | Все | Все | Всё всё |
| CROSS | - | - | Декартово произведение |
Производительность
-- INNER JOIN часто быстрее
-- Меньше данных для обработки, индексы работают эффективнее
-- LEFT JOIN может быть медленнее (больше данных)
-- FULL OUTER замедляет запрос (нужно проверить обе стороны)
-- Совет: используй INNER где возможно, только потом LEFT
Бонус: условие ON vs WHERE
-- ON фильтрует ДО соединения (важно для LEFT/RIGHT JOIN)
SELECT *
FROM users
LEFT JOIN orders ON users.id = orders.user_id AND orders.amount > 100;
-- Charlie останется, даже если нет заказов > 100
-- WHERE фильтрует ПОСЛЕ соединения
SELECT *
FROM users
LEFT JOIN orders ON users.id = orders.user_id
WHERE orders.amount > 100;
-- Charlie исчезнет (фильтр отсекает NULL)
Вывод
- INNER = пересечение (только совпадения)
- LEFT = все из левой + совпадения (самый частый)
- RIGHT = все из правой + совпадения (редко, обычно переписывают LEFT)
- FULL OUTER = объединение (все данные)
В боевых условиях 90% случаев — это INNER или LEFT JOIN.