如何通过SQL根据考勤打卡的上下班时间自动获取ShiftCode
自动匹配考勤记录与班次代码解决方案
先明确两张表结构(根据你提供的表信息整理)
- Shift表:存储班次规则,字段包含
ShiftCode(班次编码)、StartTime(班次开始时间)、EndTime(班次结束时间) - 考勤记录表:存储员工打卡数据,字段包含
EmpID(员工ID)、RecordTime(打卡日期+时间)、ShiftCode(需自动填充的班次编码)
为什么用BETWEEN会失败?
大多是因为存在跨天班次(比如夜班22:00到次日6:00),普通的BETWEEN只能判断同一天内的时间范围,没法覆盖跨天场景。
核心匹配逻辑
分两种场景处理:
- 正常班次(结束时间晚于开始时间):打卡时间的「时间部分」落在班次的开始/结束时间之间
- 跨天班次(结束时间早于开始时间):打卡时间的「时间部分」要么≥班次开始时间,要么≤班次结束时间
SQL代码实现(以MySQL为例)
直接更新考勤表的ShiftCode
UPDATE 考勤记录表 a JOIN Shift s ON -- 匹配非跨天班次 (s.EndTime > s.StartTime AND TIME(a.RecordTime) BETWEEN s.StartTime AND s.EndTime) OR -- 匹配跨天班次 (s.EndTime < s.StartTime AND (TIME(a.RecordTime) >= s.StartTime OR TIME(a.RecordTime) <= s.EndTime)) SET a.ShiftCode = s.ShiftCode;
先查询验证匹配结果(不修改数据)
SELECT a.EmpID, a.RecordTime, s.ShiftCode, s.ShiftName FROM 考勤记录表 a LEFT JOIN Shift s ON (s.EndTime > s.StartTime AND TIME(a.RecordTime) BETWEEN s.StartTime AND s.EndTime) OR (s.EndTime < s.StartTime AND (TIME(a.RecordTime) >= s.StartTime OR TIME(a.RecordTime) <= s.EndTime)) ORDER BY a.RecordTime;
额外注意点
- 如果有多个班次时间范围重叠,得加额外规则(比如绑定员工默认班次、给班次设优先级排序)
- 确保字段类型正确:
StartTime/EndTime是TIME类型,RecordTime是DATETIME/TIMESTAMP类型 - 其他数据库的适配:
- SQL Server用
CONVERT(TIME, RecordTime)替代TIME(a.RecordTime) - Oracle用
TO_CHAR(RecordTime, 'HH24:MI:SS')提取时间部分
- SQL Server用
内容的提问来源于stack exchange,提问作者Shrike1999
相关产品推荐
相关产品推荐

