JavaRush /Курсы /SQL SELF /Введение в объединение данных: JOIN

Введение в объединение данных: JOIN

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

Сегодня мы переходим к одной из самых интересных тем в работе с реляционными базами данных — объединение данных из нескольких таблиц с использованием JOIN. Это мощный инструмент, который открывает двери к созданию сложных связей и аналитики.

Представьте, что ваша база данных — это огромный комикс, где каждая разрозненная таблица является отдельным кадром. Чтобы сложить цельную историю, вам нужно соединить эти кадры. Именно с этим вам помогает JOIN. Объединение данных — это процесс, который позволяет запросу извлечь информацию из нескольких таблиц и связать её на основе заданных условий.

Реляционные базы данных построены вокруг концепции связей между таблицами. Каждая таблица хранит информацию о конкретной сущности, и для более полной картины мы часто хотим связать данные из разных таблиц. Например:

  • Таблица students содержит список студентов.
  • Таблица courses хранит список курсов.
  • Таблица enrollments показывает, кто какие курсы посещает.

Чтобы узнать, какой студент обучается на каком курсе, мы должны соединить эти таблицы. На собеседованиях разработчик, который умеет работать с JOIN, выглядит как солидно, ведь это один из самых востребованных навыков в работе с данными.

Основные виды объединений

В PostgreSQL существует несколько видов JOIN, и каждая из них специально предназначена для конкретных задач. Разберём их в общем виде, чтобы не забивать голову сложными примерами раньше времени:

Тип JOIN Описание
INNER JOIN Возвращает строки, у которых есть совпадение в обеих таблицах.
LEFT JOIN Возвращает все строки из левой таблицы, а из правой — только совпадающие.
RIGHT JOIN Возвращает все строки из правой таблицы, а из левой — только совпадающие.
FULL OUTER JOIN Возвращает все строки из обеих таблиц, заполняя NULL для отсутствующих совпадений.

Выбор одного из JOIN-ов зависит от вашей задачи:

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

Давайте разбираться с этими всеми объединениями прямо на практике.

Пример задачи — "Кто на каком курсе?"

Допустим, у нас есть три таблицы:

Таблица students

id name
1 Otto
2 Anna
3 Peter

Таблица courses

id title
101 Математика
102 Английский

Таблица enrollments

student_id course_id
1 101
2 102

Эти таблицы связаны следующим образом:

  • Поле id в students — уникальный идентификатор студента.
  • Поле id в courses — уникальный идентификатор курса.
  • В таблице enrollments столбцы student_id и course_id создают связь между студентами и курсами.

Допустим, нам нужно решить следующий вопрос: какой студент записан на какой курс?

Ответ можно получить с помощью JOIN. Мы будем соединять таблицы на основе их связей:

  • Связываем students и enrollments по id = student_id.
  • Связываем enrollments и courses по course_id = id.

Вот как будет выглядеть SQL-запрос:

SELECT students.name, courses.title
FROM enrollments
JOIN students ON enrollments.student_id = students.id
JOIN courses ON enrollments.course_id = courses.id;

Что делает этот запрос:

  • FROM enrollments — начинаем с таблицы, которая связывает студентов и курсы.
  • JOIN students ON enrollments.student_id = students.id — присоединяем к ней студентов, чтобы получить их имена.
  • JOIN courses ON enrollments.course_id = courses.id — присоединяем курсы, чтобы получить названия.

Результат будет выглядеть так:

name title
Otto Математика
Anna Английский

Обратите внимание: если у студента нет ни одного курса, он не появится в результате — потому что JOIN по умолчанию строгий (INNER JOIN). Позже мы разберем, как включать и таких студентов с помощью LEFT JOIN.

Если в таком запросе вам что-то непонятно, не волнуйтесь! Постепенно разобраться с этим — цель следующих лекций!

Зачем это нужно в реальной жизни?

Теперь, когда вы понимаете, как соединить таблицы, давайте обсудим реальный мир. Вы когда-нибудь задумывались, как работает интернет-магазин? Например, когда вы выбираете смартфон и видите отзывы других пользователей.

  1. Таблица products содержит информацию о товарах.
  2. Таблица reviews содержит отзывы покупателей.
  3. Таблица customers содержит информацию о самих покупателях

Чтобы отобразить на сайте отзывы, необходимо объединить таблицы products, reviews и customers. Это и есть JOIN в действии.

На что обратить внимание?

Прежде чем мы углубимся в JOIN на следующих лекциях, вот пара моментов, которые стоит запомнить:

  1. Порядок в JOIN важен. Например, LEFT JOIN возвращает строки из левой таблицы, поэтому, меняя порядок, вы меняете результат.
  2. Работайте с небольшими таблицами. На первых порах избегайте запроса на миллионы строк. Не забывайте, даже самый простой запрос должен быть понятным.
  3. Привыкайте думать о связях. Когда вы привыкнете видеть таблицы как части одной большой структуры, работа с JOIN станет естественной.

С сегодняшнего дня мы начнём превращаться в SQL-специалистов. В следующей лекции вы узнаете, как использовать INNER JOIN для извлечения данных из двух таблиц. Это будет значительный шаг в вашем обучении PostgreSQL.

2
Задача
SQL SELF, 11 уровень, 0 лекция
Недоступна
Использование COALESCE для обработки NULL в строках
Использование COALESCE для обработки NULL в строках
2
Задача
SQL SELF, 11 уровень, 0 лекция
Недоступна
Расчёт средней цены с условием и обработкой NULL
Расчёт средней цены с условием и обработкой NULL
Комментарии (11)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Slevin Уровень 64
4 сентября 2025
Отличные задачи, которые вообще не по теме лекции. Отличные примеры, которые вообще не про то, про что говорит лекция. Это залет, ребят - максимальный минус.
Slevin Уровень 64
4 сентября 2025
На собеседованиях разработчик, который умеет работать с JOIN, выглядит как солидно, Кто-то хочет выглядеть "как солидно"? Как солидно-снейково? "Kept you waiting, huh?"
Anemon Уровень 13 Expert
1 сентября 2025
🤓
Ra Уровень 35 Student
28 августа 2025
Также есть такая штука, как Lateral https://eax.me/postgresql-lateral-join/
Ra Уровень 35 Student
28 августа 2025
Лайфхак: если делать поля связей одинаковые, users.user_id и posts.user_id, тогда можно использовать t1 join t2 using(user_id)
Евгений Уровень 49 Expert
24 июля 2025
В первой задаче компилятор работает просто жутко криво. Вот такой результат:

project_id	project_name	manager
1	Redesign Website	Ольга
2	CRM Integration	Не назначен
3	Data Analysis	Дмитрий
4	HR Automation	Не назначен
При таком запросе:

select project_id, project_name, COALESCE(manager, 'Не назначен') as manager
from projects
order by project_name;
Сортировка не работает вообще. Хотя валидатор задачу принимает, да и сама задача выполнена правильно, просто запуск отрабатывает криво.
Игорь Уровень 14
22 июня 2025
Зачем в задаче 2 "Расчёт средней цены с условием и обработкой NULL" явно указывать условие WHERE price IS NOT NULL ведь AVG(price) и так исключает такие строки?
24 июня 2025
А если у вас в какой-то категории будут только NULL, то результат avg по данной категории вернет NULL, хотя по условию задачи having такие avg возвращающие NULL все равно отсеивает
Игорь Уровень 14
25 июня 2025
Да, в этом и вопрос был - что агрегатная функция AVG(price) совместно с условием AVG(price) > 500 и без WHERE price IS NOT NULL отсеят все NULL. Другой вопрос - что WHERE выполняется до GROUP BY и, возможно, сначала отсеять ненужные строки выгоднее с точки зрения производительности выполнения запроса... Но это только мысли, ответа тут я не знаю.
25 июня 2025
С точки зрения производительности это верно, чем больше сразу строк отсеивается тем меньше строк приходиться группировать, тем быстрее выполниться запрос, поэтому использование отсеивания по NULL на начальном этапе является логичным. В своей практике я встречал такое, что условие фильтрации выставленное не в правильном месте, сильно усложняло запрос, и как следствие приводило к нагрузке на БД и росту конектов
Евгений Уровень 49 Expert
24 июля 2025
Ну и добавлю к комментарию Дмитрия, что всё-таки запрос с явной фильтрацией на NULL является более читаемым и понятным. Понятно, что группы, где price всегда NULL будут отсеяны, но всё-таки это не столь очевидно при первом взгляде на запрос.