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 база выполняет так:
- берёт очередной маршрут из
routes; - ищет в
airplanesстроку, у которойairplane_codeсовпадает с кодом самолёта маршрута; - склеивает две строки в одну — теперь у маршрута есть и номер, и модель;
- если пары нет, маршрут при INNER JOIN в результат не попадает.
Типичные ошибки
- Неоднозначный столбец. Ошибка
column reference "city" is ambiguousзначит, что столбец есть в нескольких соединённых таблицах. Указывайте таблицу:dep.city. - Одна таблица дважды без разных псевдонимов. Чтобы получить и город вылета, и город прилёта,
airportsприсоединяют два раза:depиarr. - Неверное условие ON. Если соединить по случайному столбцу или забыть часть условия, строки «размножатся»: каждая найдёт много пар. Если результат подозрительно большой — первым делом проверьте
ON.
💡 Главное про JOIN: вFROM— первая таблица,JOINдобавляет следующую,ONописывает, по каким столбцам строки соединяются. Псевдонимы делают запрос читаемым.
Практика
8- Тест 1 — Что вернёт «routes CROSS JOIN airplanes» — соединение без условия?
- Тест 2 — Запрос с двумя соединениями airports упал с ошибкой «column reference "city" is ambiguous». В чём дело?
- Задача 1 — Места с моделью самолёта
- Задача 2 — Маршрут и город вылета
- Задача 3 — Откуда и куда
- Задача 4 — Маршруты на Boeing
- Задача 5 — Билет и его бронирование
- Задача 6 — Город вылета и модель
Задачи решаются прямо здесь, в браузере, на учебной базе — нужна только бесплатная регистрация, чтобы сохранялись ответы и прогресс.
Потренируйтесь в тренажёре
4Задачи на ту же тему, но на другой базе — продажи магазина электроники. Хороший способ проверить, что тема понятна, а не просто запомнилась на примерах урока.