簡體   English   中英

SQL 在 n:m 關系中聚合 function

[英]SQL aggregate function in n:m relationship

該域是一個航空公司預訂系統。 用戶可以預訂航班。 一個航班由一條或多條腿組成。

  ┌─────┐        ┌──────┐      ┌───────┐
  │ 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 席位可用
1 2
2 2
航班
ID
1
2
Flight_Leg
航班號 leg_id leg_order
1 1 0
1 2 1
2 1 0

注意:航班 1 有兩條腿,航班 2 只有一條腿。 兩個航班“共享”同一個第一站。

預訂
ID 航班號 number_passengers
1 1 1
2 2 1

注意:一個人預訂了航班 1 並且雙腿飛行。 另一個人只預訂了第一程航班 2。 這意味着,第一段有兩名乘客,另一段有一名乘客。

預期 output

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

航班號 free_seats
1 0
2 0

注意:航班2沒有免費座位,因為第一段已經訂滿了

ER圖

在此處輸入圖像描述

以下查詢實現了您想要的 output。 如果前一段已滿,我使用Lag function 到 go 到前一行。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM