Логотип Workflow

Article

Updated at:

Joins

Stage 4. JOIN: корректное объединение реляционных данных

JOIN — это механизм, который соединяет данные из нескольких таблиц по условию связи. В реляционной модели это базовый навык: данные почти всегда разделены по сущностям (users, orders, payments), и без JOIN невозможно собрать полноценную бизнес-картину.

Зачем вообще нужен JOIN

Представим задачу: показать список заказов вместе с именем клиента. Имя лежит в users, заказ — в orders. Если читать таблицы отдельно, вы не получите единую строку “заказ + владелец”. JOIN решает это.

Базовый шаблон:

SELECT ...
FROM left_table l
JOIN right_table r ON r.key = l.key;

Ключевой момент — условие в ON. Именно оно определяет, какие строки считаются совпавшими.

Типы JOIN от простого к сложному

1) INNER JOIN

Возвращает только строки, где есть совпадение с обеих сторон.

INNER JOIN schema

SELECT u.name, o.id AS order_id, o.amount
FROM users u
INNER JOIN orders o ON o.user_id = u.id;

Если у пользователя нет заказов, в результат он не попадет.

2) LEFT JOIN

Возвращает все строки из левой таблицы и совпадения из правой. Если совпадения нет, поля правой части будут NULL.

LEFT JOIN schema

SELECT u.name, o.id AS order_id, o.amount
FROM users u
LEFT JOIN orders o ON o.user_id = u.id;

Пользователь без заказов останется в выдаче как name + NULL.

3) RIGHT JOIN

Симметрия LEFT JOIN: возвращает все строки из правой таблицы и совпадения слева.

RIGHT JOIN schema

SELECT u.name, o.id AS order_id
FROM users u
RIGHT JOIN orders o ON o.user_id = u.id;

На практике чаще используют LEFT JOIN, потому что так легче читать запрос (от основной таблицы к дополнительной).

4) FULL OUTER JOIN

Возвращает совпадения плюс несовпавшие строки с обеих сторон.

FULL JOIN schema

SELECT u.name, o.id AS order_id
FROM users u
FULL OUTER JOIN orders o ON o.user_id = u.id;

Полезно для сверок данных и поиска “сиротских” записей.

Пример с результатом (INNER JOIN)

SELECT o.id, o.amount, o.status, u.name
FROM orders o
INNER JOIN users u ON u.id = o.user_id
ORDER BY o.id;
idamountstatusname
11200.00PAIDAnna
2300.00NEWAnna
3700.00PAIDIvan

Частые ошибки и как их избежать

  1. Нет условия ON: получается декартово произведение (взрыв количества строк).
  2. Неверный фильтр после LEFT JOIN: WHERE o.status = 'PAID' может превратить LEFT JOIN в поведение INNER JOIN.
  3. Не учитывают кардинальность: один пользователь может иметь много заказов, значит строк станет больше — это нормально.

Правильный прием для LEFT JOIN с фильтром по правой таблице:

LEFT JOIN orders o
  ON o.user_id = u.id
 AND o.status = 'PAID'

Как учить JOIN, чтобы не путаться

  1. Сначала писать INNER JOIN на двух таблицах.
  2. Потом тот же кейс переписать через LEFT JOIN и сравнить результат.
  3. Добавить третью таблицу (payments) и проверить рост числа строк.
  4. Только потом переходить к FULL OUTER JOIN и сверочным сценариям.

Практика перед следующим уроком

Возьмите таблицы users и orders и выполните 4 запроса: INNER, LEFT, RIGHT, FULL. После каждого запроса запишите ответ на вопрос: “Какие строки остались и почему?”. Это лучший способ закрепить тему.