【问题标题】:SQL aggregate function in n:m relationshipn:m 关系中的 SQL 聚合函数
【发布时间】:2021-05-12 01:57:45
【问题描述】:

该域是一个航空公司预订系统。用户可以预订航班。航班由一条或多条航段组成。

  ┌─────┐        ┌──────┐      ┌───────┐
  │ Leg ├────────┤Flight├──────┤Booking│
  └─────┘  *   * └──────┘1   * └───────┘

要向用户显示有效航班的列表,系统必须确定航班是否有空余座位。最大可用席位存储为Leg 表中的字段。预订座位存储在Booking

航班可能包含多个航段。例如,可能有 3 个航段 A -> B -> C。还有两个应该由用户预订的航班:

  1. A -> B:从 A 到 B 的航班。
  2. A -> B -> C:从 A 经 B 飞到 C。

我创建了一个dbfiddle,尝试按航段分组,这为我提供了每条航段的预订座位数。但我需要生成每段预订乘客数量最多的航班列表。在上面的示例中:如果乘客预订了航班 2,则航班 1 的可用座位可能会更少,因为他们都“共享”第一段航程。

select l.id as Leg, sum(b.number_passengers) as BookedSeats
FROM flight f
     JOIN flight_legs fl on f.id = fl.flight_id
     JOIN leg l on fl.legs_id = l.id
     JOIN booking b on f.id = b.flight_id
GROUP BY l.id;

如何创建有可用座位的航班列表?

示例

架构

id seats_available
1 2
2 2
飞行
id
1
2
Flight_Leg
flight_id leg_id legs_order
1 1 0
1 2 1
2 1 0

注意:航班 1 有两条腿,航班 2 只有一条腿。两个航班“共享”同一个第一站。

预订
id flight_id number_passengers
1 1 1
2 2 1

注意:一个人预订了 1 号航班并且双腿飞行。另一个人只预订了第一程航班 2。这意味着,第一段有两名乘客,另一段有一名乘客。

预期输出

查找所有有可用座位的航班。座位也可能被其他航班的航段占用。

flight_id free_seats
1 0
2 0

注意:航班 2 没有空位,因为第一段已经订满了

ER 图

【问题讨论】:

  • 如果可能,输入您想要的输出和样本数据
  • @LucasEthen 添加了对 dbfiddle 示例的说明。

标签: sql entity-relationship


【解决方案1】:

以下查询实现了您想要的输出。如果前一段已满,我使用Lag 函数转到上一行。

SELECT Leg,
   case
     when Free_Seats = 0 then 0 
        else (case when PrevLeg = 0 then 0 else Free_Seats end) end as Free_Seats

FROM (SELECT Leg,Free_Seats,LAG(Free_Seats,1) OVER(ORDER BY Leg) PrevLeg
  FROM (SELECT l.id AS Leg,l.seats_available,b.number_passengers,fl.flight_id,
             (max(l.seats_available) OVER(PARTITION BY fl.flight_id) - sum(b.number_passengers) OVER(PARTITION BY fl.flight_id)) AS Free_Seats,
             ROW_NUMBER() OVER(PARTITION BY fl.flight_id ORDER BY fl.flight_id) AS seq
         FROM flight f
          JOIN flight_legs fl ON f.id = fl.flight_id
          JOIN leg l ON fl.legs_id = l.id
          JOIN booking b ON f.id = b.flight_id) T
 WHERE t.seq=1) T

【讨论】:

  • 谢谢。这给了我每条腿的免费座位。但我每个航班需要免费座位。
  • 我明白了,但是你想要的输出是错误的,因为 flight_id = 1 有两条腿记录,总共有四个座位,其中还有两个座位。
  • 然后我并不清楚我的例子:第一段有来自 Booking 1 的 1 名乘客(预订了航班 1)和来自 Booking 2 的 1 名乘客(预订了航班 2)。因此,航班 1 应该提供 0 个免费座位,因为第一站预订了两个人(但针对不同的航班)。航班 2 也应该提供 0 个免费座位,因为第一段已经满员,尽管在第二段会有一个免费座位。更新了预期的输出。
  • 我实现了你的输出。我希望它是根据您的要求。
  • 很遗憾,这不起作用:无论为第 1 段设置了多少个座位 free_seats 始终为 0 (demo)。而且它不会让我乘飞机获得免费座位。相反,它提供免费座位。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多