如何用单条SQL查询计算员工多组打卡的工作时长?
单条SQL实现员工每日考勤时长统计
完全可以用单条SQL实现你的需求,核心思路是通过窗口函数对打卡记录进行配对,结合分组统计处理奇偶打卡的异常情况。以下是通用方案(以MySQL为例,其他数据库仅需微调时间计算函数):
WITH punch_pairs AS ( SELECT DATE(punch_timestamp) AS punch_date, user_id, punch_timestamp, ROW_NUMBER() OVER (PARTITION BY user_id, DATE(punch_timestamp) ORDER BY punch_timestamp) AS rn FROM timeclock ) SELECT punch_date AS date, user_id, CASE WHEN COUNT(*) % 2 != 0 THEN 'Error - missing punch' ELSE CAST(SUM( CASE WHEN rn % 2 = 0 THEN TIMESTAMPDIFF(HOUR, LAG(punch_timestamp) OVER (PARTITION BY user_id, punch_date ORDER BY rn), punch_timestamp) ELSE 0 END ) AS CHAR) END AS hours_worked FROM punch_pairs GROUP BY punch_date, user_id;
逻辑说明:
- 标记打卡顺序:用
ROW_NUMBER()窗口函数,按user_id和日期分组、打卡时间排序,给每条记录分配顺序编号。 - 配对计算单段时长:对编号为偶数的记录(下班打卡),用
LAG()函数获取前一条编号为奇数的记录(上班打卡)的时间,计算两段时间的小时差。 - 汇总与异常判断:按日期和用户分组后,先判断总打卡次数是否为奇数——若是则返回错误提示;否则求和所有有效时段的时长,转成字符串统一返回格式。
运行上述SQL后,会输出你预期的结果:
| date | user_id | hours_worked |
|---|---|---|
| 2023-04-01 | 1 | 8 |
| 2023-04-01 | 2 | 6 |
| 2023-04-01 | 3 | Error - missing punch |
内容的提问来源于stack exchange,提问作者lucky.expert
相关产品推荐
相关产品推荐

