Хорошо, вот мое решение. Немного быстрее, чем другое решение для подсчета, но не очень. Кроме того, он ограничен преобразованием в числовое значение, чтобы разрешить только минимальные и минимальные диапазоны дат. Странно, что рекурсивные CTE быстрее, чем счетные таблицы. Таблицы подсчета масштабируются лучше?
declare @Tally table
(
N int identity(1,1),
T bit
)
insert into @Tally
select TOP 11000 0 as T
from master.dbo.SysColumns sc1, master.dbo.SysColumns sc2
declare @begin datetime = (select MIN(start) from @TimeSpan);
declare @end datetime = (select MAX(finish) from @TimeSpan);
with strings as
(
select S.*
,
'1'+
REPLICATE('0', DATEDIFF(DAY, @begin, DATEADD(DAY,N-1,S.start)))+
'1'+
REPLICATE('0', DATEDIFF(DAY, DATEADD(DAY,N-1,S.start), @end)) task
from @TimeSpan S
inner join
@Tally T ON DateAdd(DAY,T.N-1,S.start) <= S.finish
)
select SUM(DISTINCT convert(numeric(38,0),task))
- COUNT(DISTINCT task)*(convert(numeric(38,0), '1' + REPLICATE('0',DATEDIFF(d,@begin,@end)+1)))
from strings