Перейти к основному содержимому
Модуль 3 · Урок 2 из 410/57 в курсе~10 min
Уроки модуля (2/4)

Оставляя все слева: LEFT JOIN

INNER JOIN из предыдущего урока имеет важный побочный эффект: он удаляет строки, которым нет совпадений. Если у сотрудника нет отдела (department_id — это NULL), они исчезнут из результата.

Иногда это то, чего ты хочешь. Однако зачастую это не так: в отчете HR важно видеть все сотрудников, в том числе без отдела, и знать, кто они. Для этого и нужен LEFT JOIN (полностью LEFT ВНЕШНЕЕ СОЕДИНЕНИЕ).

Как это работает

SQL
SELECT columns
FROM   table_a
LEFT JOIN table_b ON table_a.x = table_b.y;

Прочтите по-английски: "сохраните все строки table_a; для каждой попробуйте прикрепить строку из table_b; если совпадений нет, заполните столбцы из table_b с NULL".

Ключевое слово LEFT: оно означает «левый стол», т.е. тот, который написан после FROM. Все его строки всегда сохраняются.

SQL
-- All employees, including those without a department:
SELECT e.first_name,
       e.last_name,
       d.name AS dipartimento
FROM   employees   AS e
LEFT JOIN departments AS d ON e.department_id = d.id;

В нашем наборе данных этот запрос возвращает 10 строк (по одному сотруднику в каждой). Андреа Коста, у которого есть department_id = NULL, появляется с dipartimento = NULL вместо того, чтобы исчезнуть.

Поиск строк «нет совпадений»

Очень полезное последствие: фильтруя с помощью IS NULL в столбце в правой таблице вы найдете именно те строки без совпадений:

SQL
-- Orphan employees: no department assigned
SELECT e.first_name, e.last_name
FROM   employees   AS e
LEFT JOIN departments AS d ON e.department_id = d.id
WHERE  d.id IS NULL;

Этот трюк постоянно используется в реальном мире: "найди мне заказы без клиент", "товары без отзывов", "пользователи, которые никогда не авторизовались в".

Попробуйте это

Упражнение#sql.m3.l2.e1
Попыток: 0Загрузка…

Возвращает имя (first_name) и фамилию (last_name) сотрудников, которым НЕ назначен отдел. Одна или несколько строк, два столбца.

Загрузка редактора…
Показать подсказку

Заполните WHERE с помощью d.id IS NULL — вам нужны строки, в которых LEFT JOIN не нашел соответствующий отдел.

Решение доступно после 3 попыток

Обзор упражнения

Упражнение#sql.m3.l2.e2
Попыток: 0Загрузка…

Перечислите все отделы (departments.name) и рядом с ними количество сотрудников, включая отделы, в которых нет сотрудников (для них покажите 0). Подсказка: начните с отделов и выполните ЛЕВОЕ СОЕДИНЕНИЕ с сотрудниками, затем GROUP BY + COUNT.

Загрузка редактора…
Показать подсказку

Используйте COUNT(e.id) (а не COUNT(*)) для подсчета 0, когда совпадений нет: COUNT(*) будет считать 1 из-за строки LEFT JOIN с NULL.

Решение доступно после 3 попыток