Reputation: 81
Is it possible to sum the duration based on the number of minutes one time stamp (start, stop) within an second?
This is what I would want to do.. return the number of minutes an employee was sick during their overtime shift. The records are in segments... a sick exception may not always be within an overtime shift.
All rows would be within the same table exceptions
.
Employee Exception Start Stop
Bob OverTime 09:00 17:00
Jim OverTime 14:00 16:00
Mark OverTime 14:00 18:00
Steve OverTime 10:00 14:00
Employee Exception Start Stop
Bob Sick 09:00 09:30
Bob Sick 14:00 17:00
Jim Sick 14:00 16:00
Results:
Bob: 3.5 hours
Jim: 2 hours
Upvotes: 1
Views: 818
Reputation: 48177
SELECT O.Employee,
CAST(CAST(
DATEDIFF (
minute,
CASE WHEN S.Start < O.Start THEN O.Start
ELSE S.Start
END,
CASE WHEN S.Stop > O.Stop THEN O.Stop
ELSE S.Stop
END
) * 1.0 / 60 AS decimal (8,1)) as VARCHAR) + ' hours' as hours
FROM exceptions O -- Overtime
JOIN exceptions S -- Sick
ON O.Employee = S.Employee
AND S.[Start] <= O.[Stop]
AND S.[Stop] >= O.[Start]
WHERE
O.Exception = 'OverTime'
AND S.Exception = 'Sick'
NOTE:
sum / group by
so you test first if this are the value your needOvertime
I add
('Bob', 'Sick', '5:00', '7:00')
doesn't show up('Bob', 'Sick', '7:00', '10:00')
only show 1 hourOUTPUT
| Employee | hours |
|----------|-----------|
| Bob | 0.5 hours |
| Bob | 1.0 hours |
| Bob | 3.0 hours |
| Jim | 2.0 hours |
EDIT I add the version with SUM
SELECT O.Employee,
CAST(CAST(
SUM(DATEDIFF (
minute,
CASE WHEN S.Start < O.Start THEN O.Start
ELSE S.Start
END,
CASE WHEN S.Stop > O.Stop THEN O.Stop
ELSE S.Stop
END
) * 1.0 / 60) AS decimal (8,1)) as VARCHAR) + ' hours' as hours
FROM exceptions O -- Overtime
JOIN exceptions S -- Sick
ON O.Employee = S.Employee
AND S.[Start] <= O.[Stop]
AND S.[Stop] >= O.[Start]
WHERE
O.Exception = 'OverTime'
AND S.Exception = 'Sick'
GROUP BY O.Employee
Upvotes: 2
Reputation: 13949
SELECT
Employee,
SUM(
DATEDIFF(minute,
(CASE WHEN SickStart > OvertimeStart THEN SickStart ELSE OvertimeStart END),
(CASE WHEN SickStop > OvertimeStop THEN OvertimeStop ELSE SickStop END)
)) / 60.0 [hours]
FROM (
SELECT e1.Employee, e1.START SickStart, e1.STOP SickStop,
e2.START OvertimeStart, e2.STOP OvertimeStop
FROM Exceptions e1
JOIN Exceptions e2 ON e1.Employee = e2.Employee
AND (e1.START BETWEEN e2.START AND e2.STOP
OR e1.STOP BETWEEN e2.START AND e2.STOP)
WHERE e1.EXCEPTION = 'Sick'
AND e2.EXCEPTION = 'OverTime'
) AS t
GROUP BY Employee;
Upvotes: 3