У меня есть таблица source_flight_destination, подобная этой
Вывод должен быть таким: рейс, источник и пункт назначения.
Я придумал рабочее решение:
with ranked as (
select *,
row_number() over (partition by flight order by id asc) as rn
from source_destination_flight
),
minima as (
select flight, min(rn) as minrn from ranked group by flight ),
maxima as (
select flight, max(rn) as maxrn from ranked group by flight),
sourced as (
select
r.flight,
r.source as source
from ranked r
join minima m1 on m1.flight=r.flight and m1.minrn=r.rn
),
destination as (
select
r1.flight,
r1.destination as destination
from ranked r1
join maxima m2
on m2.flight=r1.flight and m2.maxrn=r1.rn
)
select
s.flight, s.source, d.destination from sourced s join destination d on s.flight=d.flight
Идея заключалась в следующем:
Тем не менее, это решение выглядит совершенно уродливым, и я уверен, что есть гораздо более простое решение.
Может ли кто-нибудь дать мне указания?
Для этого примера данных вы можете использовать оконную функцию FIRST_VALUE()
:
SELECT DISTINCT Flight,
FIRST_VALUE(source) OVER (PARTITION BY Flight ORDER BY ID) AS source,
FIRST_VALUE(destination) OVER (PARTITION BY Flight ORDER BY ID DESC) AS destination
FROM source_destination_flight;
Смотрите демо.
Если я правильно понял, что вы пытаетесь сделать, принимая первую строку Flight за источник и последнюю за пункт назначения, то это дает список, который вы сказали, что хотите. Я не знаю, как его производительность будет сравниваться с форпасом. Вам просто нужно попробовать.
SELECT a.Flight, a.Source, c.Destination
FROM source_destination_flight a,
(SELECT d.Flight, Min(d.id) AS Minid, Max(d.id) AS Maxid
FROM source_destination_flight d GROUP BY Flight) b,
source_destination_flight c
WHERE a.id = b.Minid
AND c.id = b.Maxid;