我有一个像这样的表 source_flight_destination
身份证 | 航班 | 来源 | 目的地 |
---|---|---|---|
1 | 靛蓝 | 二 | BB |
2 | 亚洲航空 | AA | 二 |
3 | 靛蓝 | BB | JJ |
4 | 香料喷射机 | SS | BB |
5 | 靛蓝 | JJ | SS |
6 | 亚洲航空 | 二 | KK |
7 | 香料喷射机 | BB | JJ |
输出应该是这样的航班、出发地和目的地
航班 | 来源 | 目的地 |
---|---|---|
亚洲航空 | AA | KK |
靛蓝 | 二 | SS |
香料航空 | SS | JJ |
我想出了一个可行的解决方案:
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;
查看演示。
如果我正确理解您要做什么,将航班的第一行作为源,最后一行作为目的地,那么这会生成您所说的所需列表。我不知道它的性能与forpas相比如何。你只需尝试一下即可。
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;
with ctee as
(select * from flights order by flight),
orig as (
select flight, source from (select c1.*, c2.id as id_1
from ctee as c1 left join ctee as c2 on c1.flight = c2.flight and
c1.source=c2.destination) as ad
where ad.id_1 is null),
dest as (
select flight, destination from (select c1.*, c2.id as id_1
from ctee as c1 left join ctee as c2 on c1.flight = c2.flight and
c1.destination=c2.source) as ad
where ad.id_1 is null)
select o.*, d.* from orig as o left join dest as d on o.flight = d.flight order by o.flight