Объяснение задачи Карта мест в самолете
Основная цель задачи
Задача заключается в том, чтобы создать визуальную карту мест для конкретной модели самолета (в данном случае, 'Boeing 777-300'). Результат должен представлять собой список рядов, где для каждого ряда и класса обслуживания ('Business', 'Economy', 'Comfort') показан массив доступных мест.
Например, для 1-го ряда бизнес-класса это может выглядеть так:
- Ряд: 1
- Места: ["A", "C", "D", "F"]
- Класс: Business
Логика решения (по шагам)
Шаг 1: Выбор нужного самолета.
- Прежде всего, необходимо отфильтровать данные, чтобы работать только с местами, относящимися к модели 'Boeing 777-300'.
- Для этого нужно соединить таблицу
seats(места) с таблицейaircrafts_data(данные о самолетах) по общему полюaircraft_code. - Затем в условии
WHEREуказать нужную модель самолета.
Шаг 2: Разделение номера места на ряд и букву.
- Номер места в таблице
seatsимеет формат типа12A,30K, где12- это номер ряда, аA- буква места в ряду. - Номер ряда можно получить, удалив буквенную часть из строки
seat_no. Например, с помощью функцииrtrimили регулярных выражений. - Букву места можно получить, взяв последний символ из строки
seat_no(например, функциейright).
- Номер места в таблице
Шаг 3: Группировка мест.
- Основная идея - сгруппировать все места, которые находятся в одном ряду и относятся к одному классу обслуживания (
fare_conditions). - Таким образом,
GROUP BYдолжен включать и вычисленный номер ряда, и класс обслуживания.
- Основная идея - сгруппировать все места, которые находятся в одном ряду и относятся к одному классу обслуживания (
Шаг 4: Агрегация букв мест в массив.
- Для каждой группы (например, "ряд 10, эконом-класс") нам нужно собрать все буквы мест (
A,B,Cи т.д.) в единый список или массив. - Для этого идеально подходит агрегатная функция
json_agg(в PostgreSQL), которая создает JSON-массив из значений. - Чтобы места в массиве шли в правильном порядке (A, B, C, а не C, A, B), внутри
json_aggнеобходимо добавить сортировку по букве места.
- Для каждой группы (например, "ряд 10, эконом-класс") нам нужно собрать все буквы мест (
Шаг 5: Финальная сортировка.
- Чтобы карта мест выглядела логично (ряды шли от начала к концу самолета), итоговый результат нужно отсортировать по номеру ряда.
Спойлер: ниже скрыт SQL‑запрос с решением задачи. Нажмите, чтобы раскрыть.
select
rtrim(seat_no, 'ABCDEFGHKJ')::int "row",
json_agg(right(seat_no, 1) order by right(seat_no, 1)) seats ,
fare_conditions
from seats
join aircrafts_data using(aircraft_code)
where aircrafts_data.model->>'en' = 'Boeing 777-300'
group by rtrim(seat_no, 'ABCDEFGHKJ'), fare_conditions
order by "row";