УРОК 14 / 27· ≈ 30 мин

INNER JOIN: связываем таблицы

Зачем соединять таблицы

Данные в базе нарочно разложены по разным таблицам, чтобы не повторять одно и то же. В маршруте (routes) хранится не название города, а код аэропорта (departure_airport), и не название модели, а код самолёта (airplane_code). Сами названия лежат в таблицах airports и airplanes. Чтобы собрать всё вместе — «маршрут + город вылета + модель самолёта» — таблицы нужно соединить.

Связь задаётся по совпадающим значениям: routes.departure_airport ссылается на airports.airport_code (это и есть внешний ключ, о котором мы говорили в начале курса).

Синтаксис JOIN ... ON

SELECT r.route_no, dep.city
FROM routes AS r
JOIN airports AS dep ON dep.airport_code = r.departure_airport;
  • FROM routes AS r — первая («левая») таблица с псевдонимом r;
  • JOIN airports AS dep — присоединяем вторую таблицу с псевдонимом dep;
  • ON dep.airport_code = r.departure_airport — условие соединения: какие строки считать «парой».

Псевдонимы таблиц (r, dep) почти обязательны: они короче и убирают неоднозначность, когда в разных таблицах есть столбцы с одинаковыми именами. Обращайтесь к столбцам через префикс: r.route_no, dep.city.

INNER JOIN — только совпадения

Обычный JOIN (полное имя — INNER JOIN) оставляет только те строки, для которых нашлась пара в обеих таблицах. Если у строки нет совпадения — она в результат не попадёт.

Соединяем больше двух таблиц

JOIN можно «нанизывать» — добавлять таблицы одну за другой. Одну и ту же таблицу можно присоединить дважды под разными псевдонимами — например, airports отдельно для аэропорта вылета и отдельно для аэропорта прилёта:

SELECT r.route_no, dep.city AS from_city, arr.city AS to_city
FROM routes r
JOIN airports dep ON dep.airport_code = r.departure_airport
JOIN airports arr ON arr.airport_code = r.arrival_airport;

Как связаны таблицы базы «Авиаперевозки»

Прежде чем соединять таблицы, полезно увидеть, какие столбцы их связывают. Стрелка ведёт от столбца-ссылки к столбцу, на который он ссылается:

Схема связей таблиц базы «Авиаперевозки»

Например, routes.airplane_code ссылается на airplanes.airplane_code, а у маршрута две ссылки на аэропорты — departure_airport и arrival_airport. Именно эти пары столбцов и пишут в ON.

Разбор: что делает JOIN по шагам

Запрос SELECT r.route_no, a.model FROM routes r JOIN airplanes a ON a.airplane_code = r.airplane_code база выполняет так:

  1. берёт очередной маршрут из routes;
  2. ищет в airplanes строку, у которой airplane_code совпадает с кодом самолёта маршрута;
  3. склеивает две строки в одну — теперь у маршрута есть и номер, и модель;
  4. если пары нет, маршрут при INNER JOIN в результат не попадает.

Типичные ошибки

  • Неоднозначный столбец. Ошибка column reference "city" is ambiguous значит, что столбец есть в нескольких соединённых таблицах. Указывайте таблицу: dep.city.
  • Одна таблица дважды без разных псевдонимов. Чтобы получить и город вылета, и город прилёта, airports присоединяют два раза: dep и arr.
  • Неверное условие ON. Если соединить по случайному столбцу или забыть часть условия, строки «размножатся»: каждая найдёт много пар. Если результат подозрительно большой — первым делом проверьте ON.
💡 Главное про JOIN: в FROM — первая таблица, JOIN добавляет следующую, ON описывает, по каким столбцам строки соединяются. Псевдонимы делают запрос читаемым.

Практика

8
  1. Тест 1 — Что вернёт «routes CROSS JOIN airplanes» — соединение без условия?
  2. Тест 2 — Запрос с двумя соединениями airports упал с ошибкой «column reference "city" is ambiguous». В чём дело?
  3. Задача 1 — Места с моделью самолёта
  4. Задача 2 — Маршрут и город вылета
  5. Задача 3 — Откуда и куда
  6. Задача 4 — Маршруты на Boeing
  7. Задача 5 — Билет и его бронирование
  8. Задача 6 — Город вылета и модель

Задачи решаются прямо здесь, в браузере, на учебной базе — нужна только бесплатная регистрация, чтобы сохранялись ответы и прогресс.

Зарегистрироваться и решитьВойти

Потренируйтесь в тренажёре

4

Задачи на ту же тему, но на другой базе — продажи магазина электроники. Хороший способ проверить, что тема понятна, а не просто запомнилась на примерах урока.

Строки и приведение типовСледующий урок: Внешние соединения и JOIN с группировкой