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
Возвращает только строки, где есть совпадение с обеих сторон.
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.
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: возвращает все строки из правой таблицы и совпадения слева.
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
Возвращает совпадения плюс несовпавшие строки с обеих сторон.
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;
| id | amount | status | name |
|---|---|---|---|
| 1 | 1200.00 | PAID | Anna |
| 2 | 300.00 | NEW | Anna |
| 3 | 700.00 | PAID | Ivan |
Частые ошибки и как их избежать
- Нет условия
ON: получается декартово произведение (взрыв количества строк). - Неверный фильтр после
LEFT JOIN:WHERE o.status = 'PAID'может превратитьLEFT JOINв поведениеINNER JOIN. - Не учитывают кардинальность: один пользователь может иметь много заказов, значит строк станет больше — это нормально.
Правильный прием для LEFT JOIN с фильтром по правой таблице:
LEFT JOIN orders o
ON o.user_id = u.id
AND o.status = 'PAID'
Как учить JOIN, чтобы не путаться
- Сначала писать
INNER JOINна двух таблицах. - Потом тот же кейс переписать через
LEFT JOINи сравнить результат. - Добавить третью таблицу (
payments) и проверить рост числа строк. - Только потом переходить к
FULL OUTER JOINи сверочным сценариям.
Практика перед следующим уроком
Возьмите таблицы users и orders и выполните 4 запроса: INNER, LEFT, RIGHT, FULL. После каждого запроса запишите ответ на вопрос: “Какие строки остались и почему?”. Это лучший способ закрепить тему.