SQL Server考勤系统:三班制下今日缺勤人员查询问题排查
修正三班制缺勤人员查询SQL(解决晚班跨天记录遗漏问题)
问题根源
之前的查询仅以**今日的In_Date**作为出勤判断依据,忽略了晚班(16:00-00:00)人员的跨天考勤场景:这类员工的In_Date是前一天、Out_Date是今日,导致系统误判其为缺勤。
修正思路
判断员工是否出勤的核心逻辑应该是:考勤记录的时间段与今日(00:00 至次日00:00)存在重叠,而非仅看In_Date是否为今日。具体覆盖三种场景:
- 考勤记录完全在今日范围内(早班/中班)
- 考勤记录从前一天开始、结束于今日(晚班场景)
- 考勤记录从今日开始、跨到次日(兼容极端情况)
修正后SQL示例
假设表结构
RFID_User:存储员工基础信息(UserID,UserName等)Attendance_Employees:存储考勤记录(UserID,In_DateDATETIME,Out_DateDATETIME)
SQL Server版本
-- 定义今日的日期范围 DECLARE @Today DATE = CAST(GETDATE() AS DATE); DECLARE @Tomorrow DATE = DATEADD(DAY, 1, @Today); -- 查询今日缺勤人员 SELECT u.UserID, u.UserName FROM RFID_User u WHERE NOT EXISTS ( SELECT 1 FROM Attendance_Employees ae WHERE ae.UserID = u.UserID -- 判断考勤记录与今日范围是否重叠 AND ( (ae.In_Date >= @Today AND ae.In_Date < @Tomorrow) -- 今日打卡上班 OR (ae.Out_Date >= @Today AND ae.Out_Date < @Tomorrow) -- 今日打卡下班(含前一天上班的晚班) OR (ae.In_Date < @Today AND ae.Out_Date >= @Tomorrow) -- 跨全天的极端情况 ) );
MySQL版本
-- 查询今日缺勤人员 SELECT u.UserID, u.UserName FROM RFID_User u WHERE NOT EXISTS ( SELECT 1 FROM Attendance_Employees ae WHERE ae.UserID = u.UserID -- 判断考勤记录与今日范围是否重叠 AND ( (ae.In_Date >= CURDATE() AND ae.In_Date < DATE_ADD(CURDATE(), INTERVAL 1 DAY)) OR (ae.Out_Date >= CURDATE() AND ae.Out_Date < DATE_ADD(CURDATE(), INTERVAL 1 DAY)) OR (ae.In_Date < CURDATE() AND ae.Out_Date >= DATE_ADD(CURDATE(), INTERVAL 1 DAY)) ) );
关键修正点
- 新增对
Out_Date的判断:覆盖晚班人员前一天上班、今日下班的场景 - 用日期范围而非单一日期判断:确保所有与今日有时间重叠的考勤记录都被识别为有效出勤
内容的提问来源于stack exchange,提问作者mustafa dağ
相关产品推荐
相关产品推荐

