I was just curious about your problem and made this.
Maybe not the best script, but it might give you some ideas on how to tackle the problem.
It is fully functional, but I generated the dates and you might want to use your day-table.
declare @callLogStart datetime = '2013-01-04 16:00'
declare @callLogEnd datetime = '2013-01-08 09:00'
;with dates(startDate, endDate)
as
(
select cast('2013-01-01 08:00' as datetime)
,cast('2013-01-01 17:00' as datetime)
union all
select DATEADD(day,1, startDate)
,DATEADD(day, 1, endDate)
from dates
where startDate < '2013-02-01 08:00'
)
,startDay
as
(
select *
,Datediff(hour, d.startDate, d.endDate) - DATEDIFF(hour, startDate, @callLogStart) as spent
from dates d
where @callLogStart between d.startDate and d.endDate
)
,endDay
as
(
select *
,Datediff(hour, d.startDate, d.endDate) - datediff(hour, @callLogEnd, endDate) as spent
from dates d
where @callLogEnd between d.startDate and d.endDate
)
select --SUM(spent) as actualTime
spent
,startDate
,endDate
,mark
from
(
select startDate
,endDate
,spent
,'start' as mark
from startDay
union
select startDate
,endDate
,spent
,'end'
from endDay
union
select s.startDate
,s.endDate
,-Datediff(hour, s.startDate, s.endDate)
,'remove'
from startDay s
join endDay e
on s.startDate = e.startDate
and s.endDate = e.endDate
union
select startDate
,endDate
,Datediff(hour, startDate, endDate)
,'between'
from dates
where @callLogStart < startDate
except
select startDate
,endDate
,Datediff(hour, startDate, endDate)
,'between'
from dates
where @callLogEnd < endDate
) x
order by
case mark
when 'start' then 0
when 'between' then 1
when 'end' then 2
when 'remove' then 3
end
Hope it helps