ebe*_*zer 4 sql-server sql-server-2012
我可以使用 min 和 max来让FirstIn - LastOut离开白班员工:
select
UserId,
[date],
min(convert(char(5), [Login], 108)) as FirstIN,
max(convert(char(5), LogOut,108)) as LastOUT
from Employee
group by UserId, [date]
Run Code Online (Sandbox Code Playgroud)
但我不能为夜班员工做,比如下午 5:30 到第二天早上 2:30。同一天(第二天)他们将在下午 5:30 再次到来。
select
UserId,
[date],
min(convert(char(5), [Login], 108)) as FirstIN,
max(convert(char(5), LogOut,108)) as LastOUT
from Employee
group by UserId, [date]
Run Code Online (Sandbox Code Playgroud)
UserID ShiftName Start End
2267 Night Shift-1 17:30 02:30
Run Code Online (Sandbox Code Playgroud)
UserID LogIn LogOut LogDate
2267 2016-01-04 20:52:08.000 2016-01-04 22:09:22.000 2016-01-04 00:00:00.000
2267 2016-01-04 23:00:07.000 2016-01-04 23:00:07.000 2016-01-04 00:00:00.000
2267 2016-01-05 00:35:46.000 2016-01-05 00:35:46.000 2016-01-05 00:00:00.000
2267 2016-01-05 01:02:31.000 2016-01-05 03:57:16.000 2016-01-05 00:00:00.000
2267 2016-01-05 18:43:50.000 2016-01-05 19:05:04.000 2016-01-05 00:00:00.000
2267 2016-01-05 19:10:20.000 2016-01-05 22:26:00.000 2016-01-05 00:00:00.000
2267 2016-01-05 23:27:24.000 2016-01-05 23:27:24.000 2016-01-05 00:00:00.000
2267 2016-01-06 03:45:16.000 2016-01-06 03:45:16.000 2016-01-06 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
此查询LogIn
按午夜 (0=00:00) 和班次开始之间的分钟数移动日期:
它用于获取班次的日期,然后可以在GROUP BY
.
询问:
WITH s AS (
SELECT s.UserID, e.LogIn, e.LogOut
, [DATE] = CAST(DATEADD(minute, DATEDIFF(minute, s.[Start], 0), e.LogIn) as date)
FROM @Shifts s
INNER JOIN @Employees e ON s.UserID = e.UserID
)
SELECT s.UserID, [DATE]
, FirstIN = CAST(MIN(LogIn) as time)
, LastOut = CAST(MAX(LogOut) as time)
FROM s
GROUP BY s.UserID, [DATE];
Run Code Online (Sandbox Code Playgroud)
请参阅SQL 小提琴。
输出:
UserID DATE FirstIN LastOut
2267 2016-01-04 20:52:08.0000000 03:57:16.0000000
2267 2016-01-05 18:43:50.0000000 03:45:16.0000000
Run Code Online (Sandbox Code Playgroud)
早到晚走:
如果有人迟到一点,它应该可以正常工作。
如果有人提前到达,您可以在 DATEADD 中添加一些时间,例如:
[DATE] = CAST(DATEADD(minute, 90 + DATEDIFF(minute, s.[Start], 0), e.LogIn) as date)
Run Code Online (Sandbox Code Playgroud)
这里增加了 90 分钟。这意味着,如果有人提前 90 分钟到达,则将计入当天。它将用于从 16:00 开始使用您的样本登录(17:30 - 90 分钟) 如果员工提前 2 小时(> 90 分钟)到达,则计为前一天。
工作时间:
FirstIn 和 LastOut 之间的小时数计算如下:
DATEDIFF(hour, MIN(LogIn), MAX(LogOut))
Run Code Online (Sandbox Code Playgroud)
或者像这样:
DATEADD(minute, DATEDIFF(minute, MIN(LogIn), MAX(LogOut)), CAST('' as time))
Run Code Online (Sandbox Code Playgroud)
工时输出:
UserID DATE FirstIN LastOut WorkHours WorkTime
2267 2016-01-04 20:52:08.0000000 03:57:16.0000000 7 07:05:00.0000000
2267 2016-01-05 18:43:50.0000000 03:45:16.0000000 9 09:02:00.0000000
Run Code Online (Sandbox Code Playgroud)