我正在尝试创建一个查询来计算夜班工作人员的工作时数,即。从第二天早上18:00到凌晨3:00。他们每天晚上10点到晚上11点休息。问题是创建Calc_last_Clock_Time。我似乎无法得到最后一个时钟,因为当我使用“MAX(ClockOut)”时,它给了我当天的最后一个时钟。最后一个时钟实际上是在第二天早上3:35:10。
如果我拿这样的钟表:
Name ClockTime Direction
Person A 18:00:15 IN
Person A 10:05:10 OUT
Person A 10:35:45 IN
Person A 03:35:10 OUT
我需要让这个人的第一个和最后一个时钟用于班次,以及他工作了多少小时。我还需要知道他在午餐时间工作了多长时间。我现在有以下代码。任何人都可以帮我解决这个问题吗?
; WITH emp_clock AS (
SELECT DISTINCT FullName = Pers.[Name] + ' ' + Pers.Surname,
RowNo = row_number() OVER (partition BY Pers.Personel_ID
ORDER BY C.ClockTime),
ClockDate = DATEADD(DAY, DATEDIFF(DAY, 0, C.ClockTime), 0),
DayAdj = CASE WHEN Default_Shift_End < Default_Shift_Start THEN 0
ELSE 1 END,
ClockTime = RC.ClockTime,
DirectionName = Dir.[Name],
ShiftRuleGroup = Rules.[Name],
ShiftStartTime = CONVERT(VARCHAR(10), Rules.Default_Shift_Start, 108),
ShiftEndTime = CONVERT(VARCHAR(10),
Rules.Default_Shift_End,
Rules_SRBreak = SRBreak.[Name],
BreakStartTime = SRBreak.SR_Break_StartTime,
BreakEndTime = SRBreak.SR_Break_EndTime
FROM Personnel Pers
INNER JOIN ClockIns C ON Pers.Personel_ID = C.Person_ID
INNER JOIN Direction Dir ON RC.Direction_ID = Dir.Direction_ID
INNER JOIN EmpShiftGroup ON Pers.Personel_ID =
EmpShiftGroup.Employee_ID
INNER JOIN Rules Rules ON Rules.Rules_ID = EmpShiftGroup.Rules_ID
INNER JOIN SDay ON Rules.Rules_ID = SDay.Rules_ID
LEFT OUTER JOIN SRBreak ON SRBreak.SRDay_ID = SRDay.SRDay_ID), timelog
AS (
SELECT
FullName = COALESCE(ci.FullName, co.FullName),
ClockTime = COALESCE(ci.ClockTime, co.ClockTime),
ShiftRuleGroup = COALESCE(ci.RULE, co.RULE),
ShiftStartTime = COALESCE(ci.ShiftStartTime, co.ShiftStartTime),
ShiftEndTime = COALESCE(ci.ShiftEndTime, co.ShiftEndTime),
SRBreak = COALESCE(ci.SRBreak, co.SRBreak),
BreakStartTime = COALESCE(ci.BreakStartTime, co.BreakStartTime),
BreakEndTime = COALESCE(ci.BreakEndTime, co.BreakEndTime),
ClockIn = COALESCE(ci.ClockTime, co.ClockDate - co.DayAdj + co.ShiftStartTime),
ClockOut = COALESCE(co.ClockTime, ci.ClockDate + ci.DayAdj + ci.ShiftEndTime)
FROM emp_clock ci FULL OUTER JOIN emp_clock co ON ci.Personel_ID = co.Personel_ID
AND ci.RowNo = co.RowNo - 1
AND co.ClockTime < DATEADD(DAY, 1, ci.ClockDate) + ci.ShiftStartTime
WHERE NOT (ci.DirectionName IS NULL
AND co.DirectionName = 'IN')
AND NOT (ci.DirectionName = 'OUT'
AND co.DirectionName IS NULL)
AND (ci.DirectionName = 'IN'
OR ci.DirectionName IS NULL)), detail AS (
SELECT FullName, ClockTime, ClockIn,ClockOut, ShiftStartTime, ShiftEndTime, BreakStartTime, BreakEndTime,
TimeBeforeShiftStart = CASE WHEN ClockIn - DATEADD(DAY, DATEDIFF(DAY, 0, ClockIn), 0) < ShiftStartTime THEN ClockIn - DATEADD(DAY, DATEDIFF(DAY, 0, ClockIn), 0) END,
TimeBeforeShiftEnd = CASE WHEN ClockIn - DATEADD(DAY, DATEDIFF(DAY, 0, ClockIn), 0) < ShiftStartTime THEN ShiftStartTime END,
TimeAfterShiftStart = casee WHEN ClockOut - DATEADD(DAY, DATEDIFF(DAY, 0, ClockOut), 0) > ShiftEndTime THEN ShiftEndTime END,
TimeAfterShiftEnd = CASE WHEN ClockOut - DATEADD(DAY, DATEDIFF(DAY, 0, ClockOut), 0) > ShiftEndTime THEN ClockOut - DATEADD(DAY, DATEDIFF(DAY, 0, ClockOut), 0) END
FROM timelog),
summary AS (
SELECT DISTINCT FullName, ClockDate = CONVERT(NVARCHAR(10), DATEADD(DAY, DATEDIFF(DAY, 0, ClockIn), 0),111), MIN(ClockTime) AS Calc_First_Clock,
Calc_Last_Clock = ????,
TotalWorkHours = CAST(SUM(DATEDIFF(minute, ClockIn, ClockOut) / 60.0) AS DECIMAL(4,2)),
Before_Shift = CAST(ISNULL(SUM(DATEDIFF(minute, TimeBeforeShiftStart, TimeBeforeShiftEnd)), 0) / 60.0 AS DECIMAL(4,2)),
After_Shift = CAST(ISNULL(SUM(DATEDIFF(minute, TimeAfterShiftStart, TimeAfterShiftEnd)), 0) / 60.0 AS DECIMAL(4,2))
FROM detail
GROUP BY DATEADD(DAY, DATEDIFF(DAY, 0, ClockTime), 0), Personel_ID, FullName, ClockIn,ClockOut, ShiftStartTime, ShiftEndTime, BreakStartTime, BreakEndTime )
SELECT * FROM summary