I would recommend using Eric X's approach. Given this disclaimer, this is disgusting, but it offers the means to accomplish the same thing if you do not have access to the number table for one reason or another. I am sure that it can be improved, I just wanted to try it without using a table of numbers:
Declare @Start DateTime, @End DateTime
Select @Start = '04/01/2010 09:30'
, @End = '04/01/2010 17:30'
Declare @y Table (ColleagueId Int, DepartmentId Int, DateIn DateTime, DateOut DateTime)
Insert @y
Select 1, 1, '04/01/2010 08:45' , '04/01/2010 11:45'
Union All Select 2 , 1, '04/01/2010 09:00' , '04/01/2010 12:15'
Union All Select 3 , 1, '04/01/2010 10:00' , '04/01/2010 12:00'
Union All Select 4 , 1, '04/01/2010 12:30' , '04/01/2010 17:00'
Union All Select 1 , 1, '04/01/2010 12:45' , '04/01/2010 17:15'
Union All Select 3 , 1, '04/01/2010 13:00' , '04/01/2010 17:25'
Select DateDiff(minute, @Start, @End)
- Sum(DateDiff(minute,
Case When DateIn < @Start Then @Start Else DateIn End,
Case When DateOut > @End Then @End Else DateOut End))
as UnmannedTime
From
(
Select Min(din) DateIn, dout DateOut
From
(
Select Min(y.DateIn) din, Max(y2.DateOut) dout
From @y y
Inner Join @y y2 on y.DateOut >= y2.DateIn
Where y.DateIn < @End
and y2.DateOut > @Start
Group By y.DateIn
) x
Group By dout
) q
edit added the case statements above to handle the StaffedTime calculation when a certain period starts before @Start (or ends after @End)
source
share