先準備用來排查的資料
房間可同時接不同組,總上限八人。逐組檢查看不到合計。開始加人、結束減人,同一時刻先合計變動,再逐點計人數,使用開始包含、結束不包含的時段。
以下完整建表及資料只在新的 SQLite 測試資料庫執行。全部紀錄均為假設,數量以件計,輸入的 cents 金額欄以貨幣的分存整數;計算後的平均數可能不足整分。小型例子的各表均完整列在預覽。
| 編號 | 開始時間 | 結束時間 | 人數 |
|---|---|---|---|
| B1 | 2026-10-10 09:00 | 2026-10-10 10:00 | 5 |
| B2 | 2026-10-10 09:30 | 2026-10-10 10:30 | 4 |
| 容量 |
|---|
| 8 |
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;| 查詢結果 |
|---|
| 沒有回傳資料(空結果) |
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:30 | 9 |
五人的 B1 及四人的 B2 各自都合適,但 09:30 合共九人。錯誤查詢沒有例外,更正後列出超額時點。這與獨佔房間查撞期不同,此處容許共用,重點是同時總人數。
套用前先測邊界及資料範圍
把 B2 開始改到 B1 結束一刻,先把離場及到場變動相抵,便沒有超過八人。
邊界測試要另開新的假設資料庫,重做完整建表及資料,只套用以下改動,再執行更正查詢。測試改動不可用於正式系統。
UPDATE bookings SET starts_at='2026-10-10 10:00' WHERE id='B2';| 查詢結果 |
|---|
| 沒有回傳資料(空結果) |
只有一間房及已接收的正長度預約;無效時段、取消及多資源須先驗證或分組。
以上錯誤、更正及邊界結果都已在 SQLite 執行,並與另行編寫的預期資料逐行核對。證據只適用於這組假設條件,未測其他資料庫、正式效能或你的現有資料結構。