I have 2 tables
1st table has startprocesstime and endprocesstime
2nd table has EmployeeID, StartShift and EndShift.
I need to check if the startprocesstime and Endprocesstime are still in range of my shiftschedule.
Example: Scenario 1 : Startprocesstime 2023-11-18 4:30:000 Endprocessime 2023-11-18 4:31:000
Scenario 2: Startprocesstime 2023-11-19 00:30:000 Endprocessime 2023-11-19 00:31:000
EmployeedID 4pm(StartShift) to 1am(EndShift).
One approach is to cross join the processes with the shifts and then replicate the shifts across all dates covered by each process. Note that the first candidate shift might start on the day before the process start, if that shift crosses midnight.
The process and shift date/time ranges can then be checked for overlaps using the standard test
start1 < end2 AND start2 < end1. For each overlap, the amount of overlap (in minutes) can be calculated asDATEDIFF(minute, GREATEST(start1, start2), LEAST(end1, end2)).Finally, since there are potentially multiple results with the same process/shift combination across multiple days,
GROUP BYcan be used to combine them andSUM()applied to total up the calculated overlap.The resulting query would be something like:
Sample results (with some additional test data):
Note that is the source data is limited to just Shift 1 and Process 1 and Process 2 from the original OP posted data, there is only one match with a 1 minute overlap.
See this db<>fiddle.
I had also attempted a different approach where both the shifts and the process date/time ranges were split up at all midnight crossovers and reduced to time-only ranges. Although the same results were achieved, the code was more complicated. I have not posted that source here, but have included it at the end of the above fiddle.
The above code uses the the
LEAST(),GREATEST(), andGENERATE_SERIES()functions that are new in SQL Server 2022. If you are using an older version, you will need to substitute in replacements.LEAST()andGREATEST()can be replaced withCASEexpressions. As forGENERATE_SERIES(), that gets more involved...See this db<>fiddle for code that runs with older SQL Server versions.