← Назад к вопросам

Какие знаешь виды join в SQL?

1.3 Junior🔥 211 комментариев
#SQL и базы данных

Комментарии (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_idnameorder_iduser_id
1Alice1011
2Bob1021
3Charlie1032

Результат: только 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.