Зарегистрируйтесь, чтобы продолжить обучение

LEFT JOIN (Левое внешнее соединение) SQL: Join

Ранее мы рассматривали соединение INNER JOIN. В его результат попадают только те строки, для которых нашлась пара, удовлетворяющая условию соединения. То есть там могут быть не все строки из первой или второй таблицы. Но бывают задачи, когда мы хотим построить соединение двух таблиц, но так, чтобы в нем были все строки одной из таблиц. Такие задачи можно решать с помощью LEFT JOIN и RIGHT JOIN.

Сравниваем INNER JOIN и LEFT JOIN

Рассмотрим пример с сотрудниками и отделами компании.

Таблица departments хранит информацию об отделах:

departments

department_id name
1 Development Department
2 Marketing Department
3 Finance Department
4 HR Department
5 Sales Department

Таблица employees хранит информацию о сотрудниках:

employees

employee_id department_id name salary
1 1 John Smith 50000.00
2 1 Peter Johnson 60000.00
3 2 Mary Brown 55000.00
4 2 Alex Miller 70000.00
5 3 Helen White 48000.00

View on DB Fiddle

В отделах HR (department_id = 4) и Sales (department_id = 5) пока еще нет ни одного сотрудника.

Рассмотрим, как работает левое внешнее соединение в сравнении с внутренним соединением.

Начнем с внутреннего соединения:

SELECT
    dep.name AS department,
    emp.name AS employee
FROM departments AS dep
INNER JOIN employees AS emp ON -- внутреннее соединение
    dep.department_id = emp.department_id

Результат внутреннего соединения

department employee
Development Department John Smith
Development Department Peter Johnson
Marketing Department Mary Brown
Marketing Department Alex Miller
Finance Department Helen White

View on DB Fiddle

А теперь рассмотрим левое внешнее соединение:

SELECT
    dep.name AS department,
    emp.name AS employee
FROM departments AS dep
LEFT JOIN employees AS emp ON -- левое внешнее соединение
    dep.department_id = emp.department_id

В тексте запроса почти нет отличий — вместо INNER указано слово LEFT. Результат выполнения запроса:

department employee
Development Department John Smith
Development Department Peter Johnson
Marketing Department Mary Brown
Marketing Department Alex Miller
Finance Department Helen White
Sales Department NULL
HR Department NULL

View on DB Fiddle

В результате LEFT JOIN есть все строки из результата INNER JOIN, но помимо них оно содержит еще две строки — с отделом продаж и HR. В этих отделах нет сотрудников, поэтому в качестве имени сотрудника подставляется NULL-значение.

Схематично это можно представить следующим образом:

left-join

Результат содержит все строки из первой таблицы, даже те, которые не удалось связать.

Сравниваем, как работает группировка

Рассмотрим еще один пример, который подчеркивает разницу между INNER JOIN и LEFT JOIN. Допустим, мы хотим посчитать количество сотрудников в каждом из отделов. Такую задачу мы уже решали — надо воспользоваться соединением и группировкой.

Запрос с внутренним соединением

SELECT
    dep.name AS department,
    COUNT(emp.employee_id) AS employees_count
FROM departments AS dep
INNER JOIN employees AS emp ON
    dep.department_id = emp.department_id
GROUP BY dep.name
department employees_count
Finance Department 1
Marketing Department 2
Development Department 2

View on DB Fiddle

Запрос с левым внешним соединением

SELECT
    dep.name AS department,
    COUNT(emp.employee_id) AS employees_count
FROM departments AS dep
LEFT JOIN employees AS emp ON
    dep.department_id = emp.department_id
GROUP BY dep.name
department employees_count
Sales Department 0
HR Department 0
Finance Department 1
Marketing Department 2
Development Department 2

View on DB Fiddle

Текст запросов также отличается только типом соединения. А результаты отличаются тем, что в запросе с INNER JOIN нет отделов с нулевым количеством сотрудников, а в запросе LEFT JOIN они есть. Разница снова связана с тем, как обрабатываются строки без пары.

RIGHT JOIN

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

Схематично работа RIGHT JOIN выглядит так:

right-join

Результат содержит все строки из второй таблицы, даже те, которые не удалось связать.

Запрос, в котором используется левое внешнее соединение, можно легко переписать на запрос с правым внешним соединением:

Запрос с левым внешним соединением

SELECT
    dep.name AS department,
    COUNT(emp.employee_id) AS employees_count
FROM departments AS dep
LEFT JOIN employees AS emp ON
    dep.department_id = emp.department_id
GROUP BY dep.name

View on DB Fiddle

Запрос с правым внешним соединением

SELECT
    dep.name AS department,
    COUNT(emp.employee_id) AS employees_count
FROM employees AS emp
RIGHT JOIN departments AS dep ON
    dep.department_id = emp.department_id
GROUP BY dep.name

View on DB Fiddle

Эти запросы отличаются только типом соединения и порядком таблиц. То есть можно сказать, что TableA LEFT JOIN TableB = TableB RIGHT JOIN TableA.

Выводы

LEFT JOIN используют, когда нужно построить соединение, в котором обязательно будут все строки из первой таблицы. Если для строки из первой таблицы нет подходящих пар во второй таблице, то вместо данных из второй таблицы будут подставлены NULL-значения.

RIGHT JOIN работает похожим образом, но только в результат попадают все строки из второй таблицы, а не из первой.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff