[英]SQL aggregate function in n:m relationship
該域是一個航空公司預訂系統。 用戶可以預訂航班。 一個航班由一條或多條腿組成。
┌─────┐ ┌──────┐ ┌───────┐
│ Leg ├────────┤Flight├──────┤Booking│
└─────┘ * * └──────┘1 * └───────┘
為了向用戶顯示有效航班的列表,系統必須查明航班是否有可用的免費座位。 最大可用座位存儲為Leg
表中的字段。 預訂座位存儲在Booking
中。
航班可能包括多個航段。 例如,可能有 3 條腿 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 |
航班號 | 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。 這意味着,第一段有兩名乘客,另一段有一名乘客。
查找所有有可用座位的航班。 座位也可能被其他航班的航段占用。
航班號 | free_seats |
---|---|
1 | 0 |
2 | 0 |
注意:航班2沒有免費座位,因為第一段已經訂滿了
以下查詢實現了您想要的 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.