patternsqlMinor
First-In and Last-Out times for Night Shift Employees
Viewed 0 times
shiftlastemployeesnightfirstforandtimesout
Problem
I can get FirstIn - LastOut out of Day shift employee using min and max:
But I cannot do for Night Shift employee, like 5:30 Pm to next day Morning 2:30 am. At the same day (Next day) they will come again on 5:30 pm.
Shift Table
Employee Table
Desired output
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]But I cannot do for Night Shift employee, like 5:30 Pm to next day Morning 2:30 am. At the same day (Next day) they will come again on 5:30 pm.
Shift Table
UserID ShiftName Start End
2267 Night Shift-1 17:30 02:30
Employee Table
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
Desired output
EmpId date FirstIN LastOUT
2267 2016-01-04 20:52 03:57
2267 2016-01-05 18:43 03:45
Solution
This query shifts the
It is used to get the date of the shift and it can then be used in a
Query:
See SQL Fiddle.
Output:
Arrive early, leave late:
If someone is leaving a little late, it should work fine.
If someone arrive early, you can add some time to DATEADD such as:
Here it adds 90 minutes. This means that if someone arrives up to 90 minutes early it will be counted on the current day. It will be for LogIn starting at 16:00 with your sample (17:30 - 90mins)
If an employee arrives 2h early (> 90min), it is counted as the previous day.
Working hours:
The number of hours between FirstIn and LastOut in hours is calculated like this:
Or like this:
Working hours output:
LogIn date by the number of minutes between midnight (0=00:00) and the start of the shift:- 17:30 (Start) becomes 00:00
- 2:30 becomes 9:00.
- 2016-01-06 03:45:16.0000000 becomes 2016-01-05 10:15:16.0000000
- ...
It is used to get the date of the shift and it can then be used in a
GROUP BY.Query:
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];See SQL Fiddle.
Output:
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.0000000Arrive early, leave late:
If someone is leaving a little late, it should work fine.
If someone arrive early, you can add some time to DATEADD such as:
[DATE] = CAST(DATEADD(minute, 90 + DATEDIFF(minute, s.[Start], 0), e.LogIn) as date)Here it adds 90 minutes. This means that if someone arrives up to 90 minutes early it will be counted on the current day. It will be for LogIn starting at 16:00 with your sample (17:30 - 90mins)
If an employee arrives 2h early (> 90min), it is counted as the previous day.
Working hours:
The number of hours between FirstIn and LastOut in hours is calculated like this:
DATEDIFF(hour, MIN(LogIn), MAX(LogOut))Or like this:
DATEADD(minute, DATEDIFF(minute, MIN(LogIn), MAX(LogOut)), CAST('' as time))Working hours output:
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.0000000Code Snippets
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];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[DATE] = CAST(DATEADD(minute, 90 + DATEDIFF(minute, s.[Start], 0), e.LogIn) as date)DATEDIFF(hour, MIN(LogIn), MAX(LogOut))DATEADD(minute, DATEDIFF(minute, MIN(LogIn), MAX(LogOut)), CAST('' as time))Context
StackExchange Database Administrators Q#127715, answer score: 6
Revisions (0)
No revisions yet.