A tarefa consiste em calcular a percentagem média de ocupação das aeronaves para cada classe de serviço (Executiva e Económica) discriminada por aeroportos de partida. Por outras palavras, é necessário descobrir, em média, quão cheias estavam as classes executiva e económica nos voos que partiram de cada aeroporto.
Passo 1: Recolha de Dados para Cada Voo.
total_seats).occupied_seats).flights — informação básica sobre os voos, incluindo flight_id e aircraft_code.seats — informação sobre todos os assentos em cada aeronave (aircraft_code) e a sua classe de serviço (fare_conditions).boarding_passes — informação sobre os cartões de embarque emitidos, que nos diz quais assentos foram ocupados em qual voo.LEFT JOIN para a tabela boarding_passes. Isto permite-nos contabilizar todos os assentos na aeronave, mesmo aqueles para os quais não foram emitidos cartões de embarque (ou seja, assentos vazios).Passo 2: Calcular a Ocupação para Cada Voo.
flight_id, podemos contar o número de assentos ocupados e o número total de assentos para cada classe.COUNT(...) FILTER (WHERE ...)), contamos os assentos separadamente para 'Business' e 'Economy'.(assentos_ocupados / total_assentos) * 100.Passo 3: Agregação por Aeroporto de Partida.
departure_airport).AVG(), encontramos a percentagem média de ocupação em todos os voos que partiram de um determinado aeroporto. Este será o resultado final.Assim, a solução é construída em dois níveis de agregação: primeiro por cada voo e, depois, por cada aeroporto.
with occupancy as (
select
flights.flight_id, departure_airport,
count(boarding_passes.seat_no) filter (where seats.fare_conditions = 'Business') business_occupancy,
(count(seats.seat_no) filter (where seats.fare_conditions = 'Business'))::numeric business_seats,
count(boarding_passes.seat_no) filter (where seats.fare_conditions = 'Economy') economy_occupancy,
(count(seats.seat_no) filter (where seats.fare_conditions = 'Economy'))::numeric economy_seats
from flights
join seats using (aircraft_code)
left join boarding_passes on
boarding_passes.seat_no = seats.seat_no and
boarding_passes.flight_id = flights.flight_id
where flights.actual_departure between '2017-08-01' and '2017-09-01'
group by flights.flight_id, departure_airport
) select
departure_airport,
(avg(case when business_seats > 0 then business_occupancy / business_seats end) * 100)::numeric(5, 2) average_business_occupancy,
(avg(case when economy_seats > 0 then economy_occupancy / economy_seats end) * 100)::numeric(5, 2) average_economy_occupancy
from occupancy
group by departure_airport
order by departure_airport;