夜班TIMECHECKIN与TIMECHECKOUT逻辑调整SQL技术需求
表信息与打卡数据
表名:TBLLOGFULL
| IDUser | TimeCheck |
|---|---|
| 22052939 | 2023年4月2日 21:32:45 |
| 22052939 | 2023年4月2日 21:33:45 |
| 22052939 | 2023年4月3日 6:07:52 |
| 22052939 | 2023年4月3日 6:04:52 |
| 22052939 | 2023年4月4日 6:04:52 |
| 22052939 | 2023年4月4日 18:05:54 |
| 22052939 | 2023年4月4日 14:00:52 |
| 22052939 | 2023年4月4日 14:04:54 |
| 22052939 | 2023年4月5日 2:00:52 |
| 22052939 | 2023年4月5日 14:01:54 |
| 22052939 | 2023年4月5日 22:00:52 |
| 22052939 | 2023年4月5日 22:04:54 |
当前SQL逻辑与输出
现有SQL脚本如下:
SELECT IDuser, CAST(MIN(TimeCheck) AS DATE) AS 'WORKINGDATE', CASE WHEN DATEADD(day, 1, MIN(TimeCheck)) - MAX(TimeCheck) < '11:00:00' THEN 'S3' WHEN MIN(DATEPART(hour,TimeCheck)) BETWEEN 5 AND 7 AND MAX(DATEPART(hour,TimeCheck)) BETWEEN 13 AND 18 THEN 'S1' WHEN MIN(DATEPART(hour,TimeCheck)) BETWEEN 10 AND 15 AND MAX(DATEPART(hour,TimeCheck)) BETWEEN 21 AND 23 THEN 'S2' END AS 'WORKINGSHIFT', CASE WHEN DATEADD(day, 1, MIN(TimeCheck)) - MAX(TimeCheck) < '11:00:00' THEN DATEADD(day, -1, CAST(MAX(TimeCheck) AS dateTIME)) ELSE MIN(TimeCheck) END AS 'TIMECHECKIN', CASE WHEN DATEADD(day, 1, MIN(TimeCheck)) - MAX(TimeCheck) < '11:00:00' THEN MIN(TimeCheck) ELSE MAX(TimeCheck) END AS 'TIMECHECKOUT' FROM TBllogfull GROUP BY IDuser, CAST(TimeCheck AS DATE)
当前逻辑:
- S3班次:TIMECHECKIN取前一天的最大Datetime,TIMECHECKOUT取当日的最小Datetime;
- 其他班次:TIMECHECKOUT取当日最小Datetime。
当前输出:
| IDUser | WORKINGDATE(工作日) | TIMECHECKIN(签到时间) | TIMECHECKOUT(签退时间) |
|---|---|---|---|
| 22052939 | 2023年4月2日 | 2023年4月2日 21:33:45 | 2023年4月3日 6:04:52 |
期望需求
调整后逻辑:
- S3班次:TIMECHECKIN取前一天20:00-23:00的最小Datetime,TIMECHECKOUT取当日5:00-7:00的最大Datetime;
- 其他班次:TIMECHECKOUT取当日最大Datetime。
期望输出:
| IDUser | WORKINGDATE(工作日) | TIMECHECKIN(签到时间) | TIMECHECKOUT(签退时间) |
|---|---|---|---|
| 22052939 | 2023年4月2日 | 2023年4月2日 21:33:45 | 2023年4月3日 6:07:52 |
修改后的SQL脚本
SELECT IDuser, CAST(MIN(TimeCheck) AS DATE) AS 'WORKINGDATE', CASE WHEN DATEADD(day, 1, MIN(TimeCheck)) - MAX(TimeCheck) < '11:00:00' THEN 'S3' WHEN MIN(DATEPART(hour, TimeCheck)) BETWEEN 5 AND 7 AND MAX(DATEPART(hour, TimeCheck)) BETWEEN 13 AND 18 THEN 'S1' WHEN MIN(DATEPART(hour, TimeCheck)) BETWEEN 10 AND 15 AND MAX(DATEPART(hour, TimeCheck)) BETWEEN 21 AND 23 THEN 'S2' END AS 'WORKINGSHIFT', CASE -- S3班次:取前一天20:00-23:00的最小时间 WHEN DATEADD(day, 1, MIN(TimeCheck)) - MAX(TimeCheck) < '11:00:00' THEN (SELECT MIN(t.TimeCheck) FROM TBllogfull t WHERE t.IDUser = TBllogfull.IDUser AND CAST(t.TimeCheck AS DATE) = DATEADD(day, -1, CAST(MIN(TBllogfull.TimeCheck) AS DATE)) AND DATEPART(hour, t.TimeCheck) BETWEEN 20 AND 23) ELSE MIN(TimeCheck) END AS 'TIMECHECKIN', CASE -- S3班次:取当日5:00-7:00的最大时间 WHEN DATEADD(day, 1, MIN(TimeCheck)) - MAX(TimeCheck) < '11:00:00' THEN (SELECT MAX(t.TimeCheck) FROM TBllogfull t WHERE t.IDUser = TBllogfull.IDUser AND CAST(t.TimeCheck AS DATE) = CAST(MIN(TBllogfull.TimeCheck) AS DATE) AND DATEPART(hour, t.TimeCheck) BETWEEN 5 AND 7) -- 其他班次:取当日最大时间 ELSE MAX(TimeCheck) END AS 'TIMECHECKOUT' FROM TBllogfull GROUP BY IDuser, CAST(TimeCheck AS DATE)
关键修改说明:
- S3班次TIMECHECKIN:通过子查询筛选前一天20:00-23:00的打卡记录,取最小时间作为签到时间;
- S3班次TIMECHECKOUT:通过子查询筛选当日5:00-7:00的打卡记录,取最大时间作为签退时间;
- 其他班次TIMECHECKOUT改为取当日所有打卡记录的最大时间,替换原逻辑的最小时间。
内容的提问来源于stack exchange,提问作者Pham Xuan Quynh
相关产品推荐
相关产品推荐

