跳至內容
Astera Technology

每組人數都未超額,為甚麼共用時段仍爆滿?

把開始及結束事件轉成同時人數,才知道共用場地在哪個時刻超額。

下載完整個案資料及參考答案 ↓

先準備用來排查的資料

房間可同時接不同組,總上限八人。逐組檢查看不到合計。開始加人、結束減人,同一時刻先合計變動,再逐點計人數,使用開始包含、結束不包含的時段。

以下完整建表及資料只在新的 SQLite 測試資料庫執行。全部紀錄均為假設,數量以件計,輸入的 cents 金額欄以貨幣的分存整數;計算後的平均數可能不足整分。小型例子的各表均完整列在預覽。

假設輸入:bookings
編號開始時間結束時間人數
B12026-10-10 09:002026-10-10 10:005
B22026-10-10 09:302026-10-10 10:304
下載可編輯 CSV ↓
假設輸入:room
容量
8
下載可編輯 CSV ↓
可直接執行的完整測試資料
CREATE TABLE bookings(id TEXT PRIMARY KEY,starts_at TEXT,ends_at TEXT,seats INTEGER);
CREATE TABLE room(capacity INTEGER);
INSERT INTO room VALUES (8);
INSERT INTO bookings VALUES ('B1','2026-10-10 09:00','2026-10-10 10:00',5),('B2','2026-10-10 09:30','2026-10-10 10:30',4);

重現錯誤結果,再核對更正

錯誤示範查詢:只用來重現問題
SELECT b.id,b.seats FROM bookings b CROSS JOIN room r WHERE b.seats>r.capacity ORDER BY b.id;
實際執行的錯誤示範結果
查詢結果
沒有回傳資料(空結果)
下載可編輯 CSV ↓
更正後的 SQLite 查詢
WITH changes AS (SELECT starts_at AS at,seats AS delta FROM bookings UNION ALL SELECT ends_at,-seats FROM bookings),
net AS (SELECT at,SUM(delta) AS delta FROM changes GROUP BY at),
occupancy AS (SELECT at,SUM(delta) OVER(ORDER BY at ROWS UNBOUNDED PRECEDING) AS seats FROM net)
SELECT o.at,o.seats FROM occupancy o CROSS JOIN room r WHERE o.seats>r.capacity ORDER BY o.at;
更正查詢的實際結果
變動時點人數
2026-10-10 09:309
下載可編輯 CSV ↓

五人的 B1 及四人的 B2 各自都合適,但 09:30 合共九人。錯誤查詢沒有例外,更正後列出超額時點。這與獨佔房間查撞期不同,此處容許共用,重點是同時總人數。

套用前先測邊界及資料範圍

把 B2 開始改到 B1 結束一刻,先把離場及到場變動相抵,便沒有超過八人。

邊界測試要另開新的假設資料庫,重做完整建表及資料,只套用以下改動,再執行更正查詢。測試改動不可用於正式系統。

新假設副本內的邊界改動
UPDATE bookings SET starts_at='2026-10-10 10:00' WHERE id='B2';
改動後再執行更正查詢的實際結果
查詢結果
沒有回傳資料(空結果)
下載可編輯 CSV ↓

只有一間房及已接收的正長度預約;無效時段、取消及多資源須先驗證或分組。

以上錯誤、更正及邊界結果都已在 SQLite 執行,並與另行編寫的預期資料逐行核對。證據只適用於這組假設條件,未測其他資料庫、正式效能或你的現有資料結構。

相關資源