Учебник

Оглавление

Данные из нескольких таблиц

Попробуем получить список мест в самолёте. Возьмём запрос, который возвращает данные о самолёте 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'

Всё. Больше никакой путаницы с аэропортами.