You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL查询实现用户预约时段的时间重叠校验方法

校验用户预约时间冲突的MySQL查询方案

刚好做过类似的预约系统,这个时间冲突校验的核心是正确判断两个时间段是否重叠,我给你写一套实用的查询方案,附带详细解释:

核心逻辑:如何判断时间重叠

两个时间段[开始1, 结束1]和[开始2, 结束2]存在重叠的充要条件是:
开始1 < 结束2 且 结束1 > 开始2
这个规则能覆盖所有重叠场景(包含、部分重叠),首尾相接的时段不算重叠,完全符合预约系统的常规需求。

具体查询实现

假设你的表结构是:

  • sessions:id(场次ID)、title、session_date(日期,DATE类型)、start_time(开始时间,TIME类型)、duration(时长,分钟数)
  • calendar:user_id(用户ID)、session_date(日期)、start_time(已占用时段开始)、end_time(已占用时段结束)

方式1:分步查询(更易理解调试)

先获取目标场次的完整时间范围,再校验冲突:

-- 1. 定义要校验的用户ID和目标场次ID
SET @check_user_id = 1001;
SET @target_session_id = 2001;

-- 2. 获取目标场次的时间范围,计算出结束时间
SELECT
    session_date,
    start_time,
    ADDTIME(start_time, SEC_TO_TIME(duration * 60)) AS session_end_time
INTO @target_date, @target_start, @target_end
FROM sessions
WHERE id = @target_session_id;

-- 3. 检查该用户是否有冲突的已预约记录
SELECT COUNT(*) AS conflict_count
FROM calendar
WHERE
    user_id = @check_user_id
    AND session_date = @target_date -- 不同日期直接跳过校验
    AND start_time < @target_end -- 已占用时段开始早于目标场次结束
    AND end_time > @target_start; -- 已占用时段结束晚于目标场次开始

如果conflict_count > 0,说明用户该时段已有预约,不能重复预订;等于0则可以正常预约。

方式2:合并为单查询(更简洁高效)

不用临时变量,直接关联表完成校验:

SELECT COUNT(*) AS conflict_count
FROM calendar c
JOIN sessions s ON c.session_date = s.session_date
WHERE
    c.user_id = 1001 -- 替换为实际用户ID
    AND s.id = 2001 -- 替换为要预订的场次ID
    AND c.start_time < ADDTIME(s.start_time, SEC_TO_TIME(s.duration * 60))
    AND c.end_time > s.start_time;

注意事项

  1. 字段类型适配:如果你的时间字段是DATETIME(日期+时间),那更简单,直接用DATE_ADD(s.start_datetime, INTERVAL s.duration MINUTE)计算结束时间,然后去掉session_date的判断,直接比较两个datetime范围即可。
  2. 索引优化:给calendar表添加复合索引(user_id, session_date),能大幅提升冲突校验的查询速度,尤其是用户量和预约记录多的时候。
  3. 边界处理:如果业务允许“首尾相接”的预约(比如上一场10:00结束,下一场10:00开始),那把判断条件里的<和>改成<=和>=即可,根据你的业务规则灵活调整。

内容的提问来源于stack exchange,提问作者BeingExpert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:07:21