MySQL:查找交替工作的志愿人员重复工作的起始时间
解决思路:用窗口函数分组连续工作记录
嘿,这个需求我之前做类似排班统计的时候碰到过,核心是先把连续属于同一个worker的记录归为一组,然后找到每组的起始时间,再关联前后组就能匹配到worker1开始工作后对应的worker2起始时间了。
假设你的表名叫worker_timestamps,字段是id(主键)、ts(时间戳)、worker(人员标识),咱们可以用SQL的窗口函数来实现:
-- 第一步:给连续同worker的记录打分组标识 WITH worker_groups AS ( SELECT id, ts, worker, -- 当当前worker和上一行不同时,分组号+1,否则保持同一组 SUM(CASE WHEN worker = LAG(worker) OVER (ORDER BY ts) THEN 0 ELSE 1 END) OVER (ORDER BY ts) AS group_id FROM worker_timestamps ), -- 第二步:提取每个工作分组的起始和结束时间 group_start_end AS ( SELECT group_id, worker, MIN(ts) AS start_ts, -- 该worker开始工作的时间 MAX(ts) AS end_ts -- 该worker结束工作的时间 FROM worker_groups GROUP BY group_id, worker ) -- 第三步:关联前后分组,找到worker1之后的worker2起始时间 SELECT g1.start_ts AS worker1_start_time, g2.start_ts AS worker2_start_time_after_worker1 FROM group_start_end g1 INNER JOIN group_start_end g2 ON g1.group_id = g2.group_id - 1 -- 前一个分组是worker1,后一个是worker2 WHERE g1.worker = 'worker1' AND g2.worker = 'worker2';
代码解释:
- worker_groups:用
LAG(worker) OVER (ORDER BY ts)获取上一条记录的worker,和当前worker对比,不同就生成新的分组号,这样连续同worker的记录会被分到同一个group_id里。 - group_start_end:对每个分组取最小的
ts,就是这个worker该段工作的起始时间,最大的ts是结束时间。 - 最后关联前后分组,筛选出前组是worker1、后组是worker2的记录,就能得到你要的结果了。
如果你的数据里有多个worker1→worker2的切换,这个SQL会返回所有符合的时间对,要是只需要最新的一组,可以在最后加ORDER BY g1.start_ts DESC LIMIT 1。
内容的提问来源于stack exchange,提问作者Clain29
相关产品推荐
相关产品推荐

