这可以通过参考涵盖您的数据集的适当周的列表来实现。这最容易通过使用日期表来实现,但如果不可用,通过cte 生成一个是微不足道的:
declare @t table(id int, OpeningDate date, ClosingDate date);
insert into @t values
(414, '20180101', '20180501')
,(416, '20180108', '20180501')
,(417, '20180108', '20180401')
;
declare @StartWeek date = (select dateadd(week,datediff(week,0,min(OpeningDate)),0) from @t);
declare @EndWeek date = (select dateadd(week,datediff(week,0,max(ClosingDate)),0) from @t);
with n(n) as (select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1)
,d(d) as (select top(datediff(week,@StartWeek,@EndWeek)+1) dateadd(week,row_number() over (order by (select null))-1,@StartWeek) from n n1,n n2,n n3,n n4,n n5)
select d.d as WeekStart
,count(t.id) as OpenItems
from d
left join @t as t
on t.OpeningDate <= d.d
and (t.ClosingDate > d.d
or t.ClosingDate is null
)
group by d.d
order by d.d;
输出:
+---------------------+-----------+
| WeekStart | OpenItems |
+---------------------+-----------+
| 01.01.2018 00:00:00 | 1 |
| 08.01.2018 00:00:00 | 3 |
| 15.01.2018 00:00:00 | 3 |
| 22.01.2018 00:00:00 | 3 |
| 29.01.2018 00:00:00 | 3 |
| 05.02.2018 00:00:00 | 3 |
| 12.02.2018 00:00:00 | 3 |
| 19.02.2018 00:00:00 | 3 |
| 26.02.2018 00:00:00 | 3 |
| 05.03.2018 00:00:00 | 3 |
| 12.03.2018 00:00:00 | 3 |
| 19.03.2018 00:00:00 | 3 |
| 26.03.2018 00:00:00 | 3 |
| 02.04.2018 00:00:00 | 2 |
| 09.04.2018 00:00:00 | 2 |
| 16.04.2018 00:00:00 | 2 |
| 23.04.2018 00:00:00 | 2 |
| 30.04.2018 00:00:00 | 2 |
+---------------------+-----------+
如果您的数据集太大而无法以足够快的速度执行,您可以使用其他稍微复杂的设计模式来提高查询效率。您可以在这里看到对各种选项的精彩讨论:Aggregate for each day over time series, without using non-equijoin logic