先訂清楚要判斷甚麼,再準備資料
兩段時段是否重疊,要看雙方是否都在對方結束前開始。用嚴格小於,便可容許前後兩節接續。每對只取較細編號在前,避免同一衝突列兩次或與自己比較。例子全部使用同一格式的本地時間。
以下全部是假設資料。請在新的 SQLite 測試資料庫建立各表,再執行唯讀查詢。數量以件計,金額以港元的分作整數儲存;顯示港元時除以 100。
| 編號 | 房間編號 | 開始時間 | 結束時間 | 狀態代碼 |
|---|---|---|---|---|
| B1 | R1 | 2026-10-10 09:00 | 2026-10-10 10:00 | confirmed |
| B2 | R1 | 2026-10-10 09:30 | 2026-10-10 10:30 | confirmed |
| B3 | R1 | 2026-10-10 10:30 | 2026-10-10 11:30 | confirmed |
| B4 | R2 | 2026-10-10 12:00 | 2026-10-10 13:00 | confirmed |
| B5 | R2 | 2026-10-10 12:00 | 2026-10-10 13:00 | cancelled |
CREATE TABLE rooms(id TEXT PRIMARY KEY, capacity INTEGER);
CREATE TABLE bookings(id TEXT PRIMARY KEY, room_id TEXT, starts_at TEXT, ends_at TEXT, seats INTEGER, status TEXT);
CREATE TABLE waitlist(id TEXT PRIMARY KEY, booking_id TEXT, requested_seats INTEGER, joined_at TEXT);
INSERT INTO rooms VALUES ('R1',8),('R2',4);
INSERT INTO bookings VALUES ('B1','R1','2026-10-10 09:00','2026-10-10 10:00',5,'confirmed'),('B2','R1','2026-10-10 09:30','2026-10-10 10:30',4,'confirmed'),('B3','R1','2026-10-10 10:30','2026-10-10 11:30',2,'confirmed'),('B4','R2','2026-10-10 12:00','2026-10-10 13:00',5,'confirmed'),('B5','R2','2026-10-10 12:00','2026-10-10 13:00',1,'cancelled');
INSERT INTO waitlist VALUES ('W1','B3',7,'2026-10-08 09:00'),('W2','B3',2,'2026-10-08 10:00'),('W3','B3',1,'2026-10-08 11:00');執行查詢,核對實際結果
SELECT a.id AS first_booking,b.id AS second_booking,a.room_id
FROM bookings a JOIN bookings b ON a.room_id=b.room_id AND a.id<b.id
AND a.starts_at<b.ends_at AND b.starts_at<a.ends_at
WHERE a.status='confirmed' AND b.status='confirmed'
ORDER BY a.id,b.id;| 首個預約 | 另一預約 | 房間編號 |
|---|---|---|
| B1 | B2 | R1 |
R1 的 B1 和 B2 有重疊。B2 在 10:30 結束,B3 同時開始,沒有衝突;B5 已取消,也不會與 B4 配對。報表只找出衝突,應核對兩個已確認預約再安排改期,不能由查詢自動決定保留哪個。
按資料範圍使用結果
此情境不容許兩個預約共用房間。如需清潔時間,要把緩衝加入有效時段。格式錯誤或時區不同須先處理;事後查衝突不能代替即時防止重複預約的機制。
本例的建表、資料及結果已在 SQLite 執行。套用時先在系統測試副本調整欄位及狀態規則,再與流程負責人核對預期結果。其他資料庫平台未經測試。