Учебник
Данные из нескольких таблиц
Попробуем получить список мест в самолёте. Возьмём запрос, который возвращает данные о самолёте Airbus A321-200
SELECT *
FROM bookings.aircrafts
WHERE aircrafts.model = 'Airbus A321-200'
Согласно описанию, данные о местах в самолёте содержатся в таблице seats
.
Давайте добавим эту таблицу в перечисление после FROM
:
SELECT *
FROM bookings.aircrafts, bookings.seats
WHERE aircrafts.model = 'Airbus A321-200'
Получаем не то, что хотели. В результате выводятся все места, всех самолётов. В таблице seats
есть поле, в котором содержится код самолёта, к которому относится место: aircraft_code
. Такое же поле есть и в таблице С. Укажем, что нам из предыдущей выборки нужны лишь те строки, в которых код самолёта из таблицы seats
совпадает с кодом самолёта таблицы aircrafts
:
SELECT *
FROM
bookings.aircrafts,
bookings.seats
WHERE
(aircrafts.model = 'Airbus A321-200')
AND (seats.aircraft_code = aircrafts.aircraft_code)
Вот, теперь то, что надо!
Осталось только уточнить, какие поля нам нужно вывести в результате:
SELECT
aircrafts.model,
seats.seat_no
FROM
bookings.aircrafts,
bookings.seats
WHERE
(aircrafts.model = 'Airbus A321-200')
AND (seats.aircraft_code = aircrafts.aircraft_code)
А теперь представьте, что нужно выбрать данные не из двух, а из десятка-двух таблиц. В таком случае условие WHERE
превратится в сущую мешанину, в которой очень сложно разобраться. Давайте посмотрим на ещё один способ написать запрос выше:
SELECT
aircrafts.model,
seats.seat_no
FROM
bookings.aircrafts
JOIN bookings.seats
ON seats.aircraft_code = aircrafts.aircraft_code
WHERE
aircrafts.model = 'Airbus A321-200'
Мы написали, что надо выбрать данные из таблицы aircrafts
, а к ним присоединить (JOIN
) данные таблицы seats
так, чтобы код самолёта из таблицы seats
совпадал с кодом самолёта таблицы aircrafts
.
Результат будет тем же, но запрос стал понятнее.
Давайте посмотрим, в какие рейсы отправляется наш Airbus A321-200
SELECT *
FROM
bookings.flights
JOIN bookings.aircrafts
ON aircrafts.aircraft_code = flights.aircraft_code
WHERE
aircrafts.model = 'Airbus A321-200'
или, указав только нужные поля:
SELECT
aircrafts.model,
flights.flight_no,
flights.scheduled_departure
FROM
bookings.flights
JOIN bookings.aircrafts
ON aircrafts.aircraft_code = flights.aircraft_code
WHERE
aircrafts.model = 'Airbus A321-200'
Посмотрим теперь между какими городами летает Airbus A321-200
. Добавим аропорт отправления. В таблице airports
есть названия городов и коды аэропротов. Код аэропорта отправления в таблице рейсов - departure_airport
:
SELECT
aircrafts.model,
flights.flight_no,
flights.scheduled_departure,
airports.*
FROM
bookings.flights
JOIN bookings.aircrafts
ON aircrafts.aircraft_code = flights.aircraft_code
JOIN bookings.airports
ON airports.airport_code = flights.departure_airport
WHERE
aircrafts.model = 'Airbus A321-200'
Оставим только название города отправления:
SELECT
aircrafts.model,
flights.flight_no,
flights.scheduled_departure,
airports.city
FROM
bookings.flights
JOIN bookings.aircrafts
ON aircrafts.aircraft_code = flights.aircraft_code
JOIN bookings.airports
ON airports.airport_code = flights.departure_airport
WHERE
aircrafts.model = 'Airbus A321-200'
Нам надо добавить ещё и аэропорт прибытия. Код аэропорта - в поле arrival_airport
таблицы flights
. Надо связать это поле с таблицей airports
.
Но города отправления и прибытия разные. Как же вывести для одной строки таблицы flights
разные значения airports.city
для городов отправления и прибытия?
Придётся присоединить таблицу airports
ещё раз, но уже связав её с полем arrival_airport
:
SELECT
aircrafts.model,
flights.flight_no,
flights.scheduled_departure,
airports.city
FROM
bookings.flights
JOIN bookings.aircrafts
ON aircrafts.aircraft_code = flights.aircraft_code
JOIN bookings.airports
ON airports.airport_code = flights.departure_airport
JOIN bookings.airports
ON airports.airport_code = flights.arrival_airport
WHERE
aircrafts.model = 'Airbus A321-200'
В таком виде запрос отругается на то, что таблица airports
указана несколько раз. И тут на помощь приходят псевдонимы. Давайте одну таблицу airports
называть dep_arp
, а другую - arr_arp
сокращённо от “аэропорт отправления” и “аэропорт прибытия” соответственно:
SELECT
aircrafts.model,
flights.flight_no,
flights.scheduled_departure,
dep_arp.city "Город отправления",
arr_arp.city "Город прибытия"
FROM
bookings.flights
JOIN bookings.aircrafts
ON aircrafts.aircraft_code = flights.aircraft_code
JOIN bookings.airports dep_arp
ON dep_arp.airport_code = flights.departure_airport
JOIN bookings.airports arr_arp
ON arr_arp.airport_code = flights.arrival_airport
WHERE
aircrafts.model = 'Airbus A321-200'
Всё. Больше никакой путаницы с аэропортами.