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

MySQL查询:如何合并员工的重叠与连续可用时间槽

问题

需要查询特定日期的员工可用时间,同一员工在同一天的多条重叠或连续的时间记录需要合并。

数据表结构

表名: availabilitySlots

idstaffIdstartTimeendTimedayOfWeekdate
112023-10-01 09:00:002023-10-01 13:00:00Monday2023-10-01
212023-10-01 13:00:002023-10-01 15:00:00Monday2023-10-01
322023-10-01 12:00:002023-10-01 14:00:00Monday2023-10-01
432023-10-01 09:00:002023-10-01 12:00:00Monday2023-10-01
532023-10-01 13:00:002023-10-01 15:00:00Monday2023-10-01
642023-10-01 15:00:002023-10-01 16:00:00Monday2023-10-01
742023-10-01 14:50:002023-10-01 17:30:00Monday2023-10-01
842023-10-01 17:20:002023-10-01 18:30:00Monday2023-10-01

期望结果

合并同一员工同一天内重叠/连续的时间区间,最终返回:

staffIdstartTimeendTimedayOfWeekdate
12023-10-01 09:00:002023-10-01 15:00:00Monday2023-10-01
22023-10-01 12:00:002023-10-01 14:00:00Monday2023-10-01
32023-10-01 09:00:002023-10-01 12:00:00Monday2023-10-01
32023-10-01 13:00:002023-10-01 15:00:00Monday2023-10-01
42023-10-01 14:50:002023-10-01 18:30:00Monday2023-10-01

注:staffId=1和4的多条重叠/连续记录需合并为单个区间,staffId=3的两条记录不连续,保留分开的区间

MySQL查询方案

使用窗口函数LAG()识别时间区间的连续性,再通过分组合并重叠/连续区间:

WITH ranked_slots AS (
    SELECT 
        staffId,
        startTime,
        endTime,
        dayOfWeek,
        date,
        -- 标记当前区间是否与上一个区间连续或重叠
        CASE 
            WHEN LAG(endTime) OVER (PARTITION BY staffId, date ORDER BY startTime) >= startTime 
            THEN 0 
            ELSE 1 
        END AS is_new_group
    FROM availabilitySlots
    WHERE date = '2023-10-01' -- 指定查询日期
),
grouped_slots AS (
    SELECT 
        staffId,
        startTime,
        endTime,
        dayOfWeek,
        date,
        -- 累计求和生成分组ID
        SUM(is_new_group) OVER (PARTITION BY staffId, date ORDER BY startTime) AS group_id
    FROM ranked_slots
)
SELECT 
    staffId,
    MIN(startTime) AS startTime,
    MAX(endTime) AS endTime,
    MAX(dayOfWeek) AS dayOfWeek,
    MAX(date) AS date
FROM grouped_slots
GROUP BY staffId, date, group_id
ORDER BY staffId, startTime;

逻辑说明

  1. ranked_slots CTE:按员工和日期分组,按开始时间排序,用LAG()获取上一个区间的结束时间,判断当前区间是否需要开启新分组(如果上一个区间的结束时间 >= 当前区间的开始时间,说明重叠或连续,属于同一组)。
  2. grouped_slots CTE:对is_new_group累计求和,生成唯一的分组ID,同一组的区间会得到相同的group_id。
  3. 最终查询:按员工、日期、分组ID聚合,取每组的最小开始时间和最大结束时间,得到合并后的区间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 09:58:09