LEFT JOIN vs RIGHT JOIN в SQL — в чём разница
Коротко
LEFT JOIN сохраняет все строки из левой таблицы и подставляет NULL, если в правой нет совпадения. RIGHT JOIN делает ровно наоборот — сохраняет все строки из правой таблицы. На практике RIGHT JOIN почти не встречается: любой RIGHT JOIN можно переписать как LEFT JOIN, поменяв таблицы местами.
Что такое LEFT JOIN
LEFT JOIN (или LEFT OUTER JOIN) возвращает все строки из таблицы в FROM (левой), даже если в правой таблице нет совпадения по ключу. Для строк без пары колонки правой таблицы заполняются NULL.
SELECT u.user_id, u.name, o.order_id, o.amount
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id;Допустим, у нас 4 пользователя и 3 заказа:
users:
| user_id | name |
|---|---|
| 1 | Анна |
| 2 | Борис |
| 3 | Вика |
| 4 | Глеб |
orders:
| order_id | user_id | amount |
|---|---|---|
| 101 | 1 | 500 |
| 102 | 1 | 300 |
| 103 | 3 | 700 |
Результат LEFT JOIN:
| user_id | name | order_id | amount |
|---|---|---|---|
| 1 | Анна | 101 | 500 |
| 1 | Анна | 102 | 300 |
| 2 | Борис | NULL | NULL |
| 3 | Вика | 103 | 700 |
| 4 | Глеб | NULL | NULL |
Все 4 пользователя на месте. У Бориса и Глеба нет заказов — в колонках order_id и amount стоят NULL.
Что такое RIGHT JOIN
RIGHT JOIN (или RIGHT OUTER JOIN) работает зеркально: сохраняет все строки из правой таблицы, а из левой подставляет NULL при отсутствии совпадения.
SELECT u.user_id, u.name, o.order_id, o.amount
FROM users u
RIGHT JOIN orders o ON u.user_id = o.user_id;Добавим заказ от удалённого пользователя:
| order_id | user_id | amount |
|---|---|---|
| 101 | 1 | 500 |
| 102 | 1 | 300 |
| 103 | 3 | 700 |
| 104 | 99 | 200 |
Результат RIGHT JOIN:
| user_id | name | order_id | amount |
|---|---|---|---|
| 1 | Анна | 101 | 500 |
| 1 | Анна | 102 | 300 |
| 3 | Вика | 103 | 700 |
| NULL | NULL | 104 | 200 |
Заказ 104 с user_id = 99 попал в результат, хотя такого пользователя нет в таблице users. LEFT JOIN бы его отбросил.
Ключевые отличия
| LEFT JOIN | RIGHT JOIN | |
|---|---|---|
| Какие строки сохраняет | Все из левой таблицы | Все из правой таблицы |
| NULL-строки | В колонках правой таблицы | В колонках левой таблицы |
| Порядок таблиц | Важен | Важен |
| Частота использования | Повсеместно | Крайне редко |
| Читаемость | Привычна всем | Путает коллег |
Главное: A LEFT JOIN B эквивалентен B RIGHT JOIN A. Результат одинаковый, меняется только порядок таблиц в запросе.
Почему RIGHT JOIN почти не используют
Три причины:
- Любой RIGHT JOIN переписывается как LEFT JOIN. Достаточно поменять таблицы местами — результат не изменится.
- Привычка чтения. SQL читается слева направо, сверху вниз. Главная таблица в FROM — логичная точка отсчёта. LEFT JOIN сохраняет именно её.
- Код-ревью и поддержка. Смешивание LEFT и RIGHT JOIN в одном запросе с несколькими соединениями запутывает. Проще использовать только LEFT JOIN.
-- RIGHT JOIN (непривычно)
SELECT o.order_id, u.name
FROM orders o
RIGHT JOIN users u ON u.user_id = o.user_id;
-- Тот же результат через LEFT JOIN (привычно)
SELECT o.order_id, u.name
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id;Если на собеседовании спросят — покажите, что знаете RIGHT JOIN, но объясните, почему на практике его заменяют LEFT JOIN.
FULL OUTER JOIN
Для полноты: FULL OUTER JOIN сохраняет все строки из обеих таблиц. Если совпадения нет ни с одной стороны — подставляет NULL. Используется редко, например, для сверки данных из двух источников.
SELECT u.user_id, u.name, o.order_id
FROM users u
FULL OUTER JOIN orders o ON u.user_id = o.user_id;Подробнее о всех типах соединений — в шпаргалке по JOIN.
Типичная ошибка
Фильтрация правой таблицы в WHERE вместо ON при LEFT JOIN:
-- Неправильно: LEFT JOIN превращается в INNER JOIN
SELECT u.name, o.order_id
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id
WHERE o.status = 'completed';
-- Правильно: условие в ON
SELECT u.name, o.order_id
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id
AND o.status = 'completed';В первом варианте WHERE отсекает строки, где o.status IS NULL — а это все пользователи без заказов. LEFT JOIN теряет смысл и работает как INNER JOIN.
Вопросы с собеседований
В чём разница между LEFT JOIN и RIGHT JOIN?
LEFT JOIN сохраняет все строки из левой таблицы, RIGHT JOIN — из правой. Результат A LEFT JOIN B идентичен B RIGHT JOIN A.
Почему RIGHT JOIN не используют на практике? Потому что любой RIGHT JOIN можно переписать как LEFT JOIN, поменяв таблицы местами. LEFT JOIN привычнее и проще читается.
Как найти пользователей без заказов через LEFT JOIN? LEFT JOIN users с orders, затем WHERE orders.user_id IS NULL. Это стандартный паттерн — anti-join.
Что вернёт LEFT JOIN, если в правой таблице несколько совпадений? По строке на каждое совпадение. Пользователь с 3 заказами появится 3 раза. Количество строк может превысить размер левой таблицы.
Можно ли смешивать LEFT и RIGHT JOIN в одном запросе? Технически да, но это антипаттерн. Перепишите через LEFT JOIN и поменяйте порядок таблиц — запрос станет понятнее.
Потренируйтесь решать задачи — откройте тренажёр с 1500+ вопросами для подготовки к собеседованиям аналитиков.
FAQ
LEFT JOIN и LEFT OUTER JOIN — это одно и то же?
Да. Слово OUTER необязательно в стандартном SQL. LEFT JOIN и LEFT OUTER JOIN — синонимы. То же касается RIGHT JOIN и RIGHT OUTER JOIN.
Когда RIGHT JOIN всё-таки оправдан?
Почти никогда. Единственный случай — если в запросе уже сложная цепочка LEFT JOIN и добавление ещё одной таблицы «справа» удобнее, чем перестройка всего запроса. Но это скорее исключение.
Влияет ли тип JOIN на производительность?
LEFT JOIN и RIGHT JOIN по производительности одинаковы — это одна и та же операция с разным порядком таблиц. Оптимизатор обрабатывает их идентично.
Потренируйте JOIN-запросы на реальных задачах с собеседований в SQL-тренажёре или посмотрите 1500+ примеров вопросов.