如何基于时间段过滤booking table中存在时间重叠的记录?
判断预订时间段是否重叠的SQL逻辑实现
背景与数据
我有一张存储预订信息的booking表,结构和现有数据如下:
| id | date | starttime | endtime |
|---|---|---|---|
| 1 | 21/12/2022 | 10:00:00 | 11:00:00 |
| 2 | 21/12/2022 | 11:00:00 | 12:00:00 |
需要实现逻辑:判断指定的时间段(同一天内)是否与已有预订存在重叠,示例场景如下:
- 9:30:00 至 11:30:00:存在重叠
- 10:45:00 至 11:45:00:存在重叠
- 10:00:00 至 14:00:00:存在重叠
- 12:00:00 至 13:00:00:无重叠
核心判断逻辑
两个时间段(A: [startA, endA],B: [startB, endB])存在重叠的本质是:A的开始时间早于B的结束时间,且A的结束时间晚于B的开始时间。
结合你的表结构,需要先限定日期匹配(确保是同一天的预订),再应用上述时间重叠规则。
SQL查询实现
假设要验证的目标日期为@target_date,目标时间段的开始/结束时间为@target_start、@target_end,可以用EXISTS子查询快速判断是否存在重叠记录:
SELECT EXISTS ( SELECT 1 FROM booking WHERE date = @target_date AND starttime < @target_end AND endtime > @target_start ) AS is_overlap;
查询结果为1表示存在重叠,0表示无重叠。
示例验证
针对给出的测试场景逐一验证:
- 9:30-11:30:匹配id=1(10:00 < 11:30 且 11:00 > 09:30)、id=2(11:00 < 11:30 且 12:00 > 09:30),返回
1(重叠) - 10:45-11:45:匹配id=1(10:00 < 11:45 且 11:00 > 10:45)、id=2(11:00 < 11:45 且 12:00 > 10:45),返回
1 - 10:00-14:00:匹配id=1(10:00 < 14:00 且 11:00 > 10:00)、id=2(11:00 < 14:00 且 12:00 > 10:00),返回
1 - 12:00-13:00:所有预订的
endtime均为12:00,不满足endtime > 12:00,返回0(无重叠)
优化建议
如果你的数据库支持datetime类型,建议将date和starttime合并为start_datetime,endtime改为end_datetime,这样不仅能简化判断逻辑,还能支持跨天的预订场景,示例SQL如下:
SELECT EXISTS ( SELECT 1 FROM booking WHERE start_datetime < @target_end_datetime AND end_datetime > @target_start_datetime ) AS is_overlap;
内容的提问来源于stack exchange,提问作者Alvin
相关产品推荐
相关产品推荐

