Чем отличаются INNER JOIN и LEFT JOIN в PostgreSQL?
INNER JOIN
INNER JOIN возвращает только те строки, для которых есть совпадение в обеих соединяемых таблицах по условию join. Если для строки левой таблицы не находится соответствующая строка в правой (или наоборот), такая строка полностью исключается из результата.
SELECT users.id, users.name, orders.id AS order_id
FROM users
INNER JOIN orders ON orders.user_id = users.id;
В результат попадут только пользователи, у которых есть хотя бы один заказ. Пользователи без заказов исчезнут из выборки полностью.
LEFT JOIN (LEFT OUTER JOIN)
LEFT JOIN возвращает все строки левой таблицы независимо от того, нашлось ли совпадение в правой. Если совпадения нет, столбцы правой таблицы заполняются NULL.
SELECT users.id, users.name, orders.id AS order_id
FROM users
LEFT JOIN orders ON orders.user_id = users.id;
Здесь в результате будут все пользователи. У тех, кто не сделал ни одного заказа, order_id будет NULL.
Основное отличие
- INNER JOIN — фактически пересечение множеств: строка попадает в результат, только если совпадение найдено с обеих сторон.
- LEFT JOIN — все строки левой таблицы плюс совпадения из правой; отсутствие совпадения не убирает строку, а даёт NULL в столбцах правой таблицы.
- При связи один-ко-многим LEFT JOIN, как и INNER JOIN, размножает строки левой таблицы по числу совпадений справа.
Важный нюанс: условие в WHERE ломает LEFT JOIN
Если после LEFT JOIN добавить условие на столбец правой таблицы в WHERE, NULL-строки отфильтруются и LEFT JOIN фактически превратится в INNER JOIN.
-- Неправильно: LEFT JOIN незаметно превращается в INNER JOIN
SELECT *
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE o.status = 'paid';
-- Правильно: условие на правую таблицу — внутри ON
SELECT *
FROM users u
LEFT JOIN orders o ON o.user_id = u.id AND o.status = 'paid';
Когда что использовать
- INNER JOIN — когда нужны только связанные записи (например, отчёт по существующим заказам).
- LEFT JOIN — когда важно сохранить все записи "главной" таблицы, даже без связей (например, показать всех пользователей, включая тех, кто ничего не купил, чтобы посчитать конверсию).
Что хочет услышать интервьюер
Понимание, что INNER JOIN исключает несовпадающие строки, а LEFT JOIN сохраняет все строки левой таблицы
Знание, что при LEFT JOIN отсутствующие совпадения справа заполняются NULL
Понимание разницы между условием в ON и в WHERE и того, как WHERE может 'испортить' LEFT JOIN
Умение привести практический пример (пользователи без заказов)
Понимание, когда какой join уместнее использовать на практике
Пример: INNER JOIN: только пользователи с заказами
SELECT u.id, u.name, o.id AS order_id
FROM users u
INNER JOIN orders o ON o.user_id = u.id;
Пример: LEFT JOIN: все пользователи, включая без заказов
SELECT u.id, u.name, o.id AS order_id
FROM users u
LEFT JOIN orders o ON o.user_id = u.id;
-- у пользователей без заказов order_id будет NULL
Типичные ошибки
Кандидат не знает, что LEFT JOIN — это то же самое, что LEFT OUTER JOIN
Забывает, что фильтрация по столбцу правой таблицы в WHERE превращает LEFT JOIN в INNER JOIN
Не понимает, что отсутствующие значения после LEFT JOIN — это NULL, а не 0 или пустая строка, и ошибается при использовании COUNT
Путает, какая таблица левая, а какая правая, при объяснении направления join
Не может объяснить, почему количество строк результата растёт при связи один-ко-многим


