JavaRush /Курсы /SQL SELF /Использование LEFT JOIN: включение всех дан...

Использование LEFT JOIN: включение всех данных из левой таблицы

SQL SELF
11 уровень , 2 лекция
Открыта

Представьте, что у вас есть две таблицы: список студентов и список их записей на курсы. Не все студенты записаны на курсы, и вы хотите увидеть полный список всех студентов, включая тех, кто по каким-то причинам курса еще не выбрал. С помощью 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, если дубли не нужны.

2
Задача
SQL SELF, 11 уровень, 2 лекция
Недоступна
Полный список студентов и их курсов
Полный список студентов и их курсов
2
Задача
SQL SELF, 11 уровень, 2 лекция
Недоступна
Полный список продуктов и их продаж
Полный список продуктов и их продаж
Комментарии (22)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Ana Уровень 14
7 февраля 2026
Как видите, в результате остались все студенты, даже Сергей, который... Peter 👀
Анатолий Уровень 53
28 января 2026
что то я не совсем понял зачем требуется такая группировка GROUP BY p.product_id, p.product_name; Это может сильно запутать новичков. В данной задаче группировка нужна и достаточна по product_name
Slevin Уровень 59
4 сентября 2025
Для Сергея в столбце course стоит NULL. Ну вашу ж мать... Ну НЕТ у вас там СЕРГЕЯ в принципе! 😶 Первый пример повторяет то, что написано ТОЛЬКО ЧТО ДО НЕГО! Ненужные дубли Если данные в правой таблице содержат дублирующиеся записи, результат запроса будет содержать больше строк, чем вы ожидаете. Внимательно смотрите на данные, с которыми работаете, и используйте DISTINCT, если дубли не нужны. Ненужные дубли это ваши 35 лекций про NULL повторяющие друг друга. Вторая задача: Используйте COALESCE(SUM(sales.quantity), NULL) вместо... Вы здоровые?
Anemon Уровень 13 Expert
4 сентября 2025
Сегодня вышел курс Java 25. Я очень-очень люблю курс по джаве, он был замечательный. Но если новый такой же по качеству как этот... Хочу верить что нет.
Denis Murashko Уровень 49
25 августа 2025
правильно решение не подходит, это интересно
Ra Уровень 1 Student
25 июля 2025
Зато 2 задача запомнится))) Вернусь как починят
Евгений Уровень 49 Expert
24 июля 2025
Вторая задача просто неправильная. Условия противоречат друг-другу. Невозможно делать группировку по product_id, а в результате выводить product_name. Хорошо, я догадался, что надо группировать и по product_id, и по product_name. Но вообще условия просто неправильные.
Aleksandr Torhov Уровень 16
21 июля 2025
Скачал решение, а оно не подходит. Жесть))
Anonymous #3080756 Уровень 45
19 июля 2025
Был Peter, а стал Сергей... ))) В целом, видно, что курс очень и очень сырой: много опечаток, "брошенные" наполовину слова, несоответствия в теории и итоговых вопросах и т.п. Видимо, курс делался совсем на скорую руку. Но кто, действительно, хочет заниматься, тот может выжать максимум полезного из курса. Задания даются максимально подробно, на мой взгляд, даже слишком: можно не думать, а просто написать решение по требованиям. Самое эффективное - прочитать только задание и, не читая предварительно требования, попробовать составить запрос самостоятельно (в файле init.sql можно увидеть структуру и тестовые данные таблиц), а потом уже сравнить свой результат с требованиями, т.к. там могут быть важные уточнения: какие колонки в каком порядке должны выводиться, например.
Иван Фетисов Уровень 4
11 июля 2025
Вторая задача: Логический тупик, при

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

SELECT
    p.product_name, -- Выбираем имя продукта из таблицы products
    SUM(s.quantity) AS total_sold -- Суммируем количество продаж из таблицы sales
FROM
    products p
LEFT JOIN
    sales s
ON
    p.product_id = s.product_id -- Связываем таблицы по product_id
GROUP BY
    p.product_id, p.product_name; -- Группируем данные по идентификатору и имени продукта
пишет Используйте `SUM(s.quantity) AS total_sold` и добавьте условие `CASE WHEN SUM(s.quantity) IS NULL THEN NULL ELSE SUM(s.quantity) END AS total_sold` для получения NULL, если продаж нет. Хотя мое решение верное и полностью совпадает с правильным :)