使用sql查找源和最终目的地

问题描述 投票:0回答:3

我有一个像这样的表 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

这个想法是:

  • 给出按航班分组的 row_number() 作为分区,
  • 找到每个分区的 row_number 的最小值和最大值,
  • 通过根据最小值和最大值进行过滤来选择源和目的地。

然而这个解决方案看起来非常丑陋,我确信有一个更简单的解决方案。

有人可以指点我吗?

mysql sql group-by distinct window-functions
3个回答
4
投票

对于此示例数据,您可以使用窗口函数

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;

查看演示


1
投票

如果我正确理解您要做什么,将航班的第一行作为源,最后一行作为目的地,那么这会生成您所说的所需列表。我不知道它的性能与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;

0
投票
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
© www.soinside.com 2019 - 2024. All rights reserved.