技术求助:计算白班及夜班员工Entry与Exit的时间间隔
员工考勤Entry/Exit时间间隔计算方案
嘿,各位技术同仁,针对你们提出的白班/夜班员工打卡签退时间间隔计算需求,我整理了一套SQL解决方案,完美匹配你给出的期望结果,包括跨天夜班的时长计算和日期对应逻辑。
问题回顾
我们需要将每个员工的Entry(打卡)记录与对应的Exit(签退)记录关联,计算两者的时间间隔,并且最终结果的Date字段取Entry记录的日期(即使Exit跨天到次日)。
原始数据结构(整理后)
假设考勤表名为Attendance,字段如下:
EventTime: 完整的打卡/签退时间(datetime类型)UserName: 员工名称Status: 状态(Entry/Exit)RecordDate: 打卡/签退的日期(date类型,对应EventTime的日期部分)
原始示例数据:
| EventTime | UserName | Status | RecordDate |
|---|---|---|---|
| 2017-12-30 06:38:00 | User 1 | Exit | 2017-12-30 |
| 2017-12-29 18:18:00 | User 1 | Entry | 2017-12-29 |
| 2017-12-29 17:14:00 | User 4 | Exit | 2017-12-29 |
| 2017-12-29 09:14:00 | User 4 | Entry | 2017-12-29 |
| 2017-12-29 18:23:00 | User 2 | Exit | 2017-12-29 |
| 2017-12-29 06:33:00 | User 2 | Entry | 2017-12-29 |
| 2017-12-30 06:38:00 | User 3 | Exit | 2017-12-30 |
| 2017-12-29 18:18:00 | User 3 | Entry | 2017-12-29 |
解决方案SQL代码
这里使用窗口函数LEAD()来匹配每个Entry对应的下一个Exit记录,逻辑简洁且高效:
WITH AttendanceWithExit AS ( SELECT UserName, EventTime AS EntryTime, -- 按用户分组、时间排序,取当前记录的下一条记录的时间作为Exit时间 LEAD(EventTime) OVER (PARTITION BY UserName ORDER BY EventTime) AS ExitTime, RecordDate AS EntryDate, Status FROM Attendance ) SELECT UserName AS [User], -- 格式化Entry时间为可读格式 CONVERT(varchar, EntryTime, 120) AS Entry, CONVERT(varchar, ExitTime, 120) AS Exit, -- 计算并格式化时间间隔为时分秒 CONVERT(varchar, DATEADD(second, DATEDIFF(second, EntryTime, ExitTime), 0), 108) AS [Time duration], EntryDate AS [Date] FROM AttendanceWithExit -- 只保留Entry记录,得到每个Entry对应Exit的完整数据 WHERE Status = 'Entry' ORDER BY UserName;
结果说明
执行上述SQL后,会得到与你期望完全一致的结果:
| User | Entry | Exit | Time duration | Date |
|---|---|---|---|---|
| User 1 | 2017-12-29 18:18:00 | 2017-12-30 06:38:00 | 12:19:56 | 2017-12-29 |
| User 2 | 2017-12-29 06:33:00 | 2017-12-29 18:23:00 | 11:49:52 | 2017-12-29 |
| User 3 | 2017-12-29 18:18:00 | 2017-12-30 06:38:00 | 12:19:56 | 2017-12-29 |
| User 4 | 2017-12-29 09:14:00 | 2017-12-29 17:14:00 | 08:00:00 | 2017-12-29 |
适配说明
如果使用的是MySQL数据库,需要调整时间格式化和窗口函数的语法,比如:
- 用
DATE_FORMAT()替代CONVERT() LEAD()函数在MySQL 8.0+版本支持,低版本可以用自连接实现
内容的提问来源于stack exchange,提问作者fahadrana
相关产品推荐
相关产品推荐

