Представьте, что у вас есть две таблицы: список студентов и список их записей на курсы. Не все студенты записаны на курсы, и вы хотите увидеть полный список всех студентов, включая тех, кто по каким-то причинам курса еще не выбрал. С помощью INNER JOIN вы увидите только тех, кто записан на курсы, но как быть с остальными студентами? Для этого и существует LEFT JOIN.
LEFT JOIN возвращает все строки из левой таблицы (определенной первым в запросе) и соответствующие строки из правой таблицы. Если соответствий нет, для колонок правой таблицы будут возвращены NULL значения.
Синтаксис LEFT JOIN
SELECT
таблица1.колонка1,
таблица1.колонка2,
таблица2.колонка1,
таблица2.колонка2
FROM
таблица1 LEFT JOIN таблица2
ON
таблица1.общая_колонка = таблица2.общая_колонка;
таблица1— это "левая" таблица.таблица2— это "правая" таблица.общая_колонка— общий столбец, по которому происходит объединение.
Пример на пальцах
Если таблица students выглядит так:
| student_id | name |
|---|---|
| 1 | Otto |
| 2 | Anna |
| 3 | Peter |
А таблица enrollments выглядит так:
| enrollment_id | student_id | course |
|---|---|---|
| 1 | 1 | Математика |
| 2 | 1 | Физика |
| 3 | 2 | Биология |
Тогда запрос:
SELECT
students.name,
enrollments.course
FROM
students LEFT JOIN enrollments
ON
students.student_id = enrollments.student_id;
выдаст:
| name | course |
|---|---|
| Otto | Математика |
| Otto | Физика |
| Anna | Биология |
| Peter | NULL |
Как видите, в результате остались все студенты, даже Сергей, который еще не записался ни на один курс. Для Сергея в столбце course стоит NULL.
Примеры использования LEFT JOIN
Пример 1: Получение списка всех студентов и их курсов
Рассмотрим задачу: нам нужно получить полный список студентов вместе с курсами, на которые они записаны, если таковые имеются. Если студент еще не выбрал курс, это тоже должно быть отображено.
Тот же запрос:
SELECT
students.name,
enrollments.course
FROM
students LEFT JOIN enrollments
ON
students.student_id = enrollments.student_id;
Результат:
| name | course |
|---|---|
| Otto | Математика |
| Otto | Физика |
| Anna | Биология |
| Peter | NULL |
Это классический пример использования LEFT JOIN.
Пример 2: Вывод продуктов и их продаж
Допустим, у вас есть две таблицы:
Таблица products, содержащая все продукты:
| product_id | product_name |
|---|---|
| 1 | Смартфон |
| 2 | Планшет |
| 3 | Ноутбук |
Таблица sales, содержащая данные о продажах:
| sale_id | product_id | quantity |
|---|---|---|
| 1 | 1 | 5 |
| 2 | 1 | 3 |
| 3 | 2 | 2 |
Теперь вы хотите увидеть все продукты и количество их продаж, включая те продукты, которые еще не были проданы.
SELECT
products.product_name,
SUM(sales.quantity) AS total_sold
FROM
products LEFT JOIN sales
ON
products.product_id = sales.product_id
GROUP BY
products.product_name;
Результат:
| product_name | total_sold |
|---|---|
| Смартфон | 8 |
| Планшет | 2 |
| Ноутбук | NULL |
Особенности и проблемы при использовании LEFT JOIN
Всегда ли нужен NULL?
Иногда LEFT JOIN добавляет NULL там, где вы его не ожидали. В таких случаях можно заменить NULL на понятное значение с помощью функции COALESCE().
SELECT
students.name,
COALESCE(enrollments.course, 'Курс не выбран') AS course
FROM
students LEFT JOIN enrollments
ON
students.student_id = enrollments.student_id;
Результат:
| name | course |
|---|---|
| Otto | Математика |
| Otto | Физика |
| Anna | Биология |
| Peter | Курс не выбран |
Ненужные дубли
Если данные в правой таблице содержат дублирующиеся записи, результат запроса будет содержать больше строк, чем вы ожидаете. Внимательно смотрите на данные, с которыми работаете, и используйте DISTINCT, если дубли не нужны.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ