这为您提供@start 和@end 之间每一天的天数:
declare @start date = '20151001', @end date = '20151017'
Select c = DATEDIFF(DAY, @start, @end)/ 7
+ case when (7 + DATEPART(WEEKDAY, @start) + (DATEDIFF(DAY, @start, @end)% 7) - d) % 7 <= (DATEDIFF(DAY, @start, @end)%7) then 1 else 0 end
From (values(1), (2), (3), (4), (5), (6), (7)) as days(d)
输出:
Day 1 2
Day 2 2
Day 3 2
Day 4 2
Day 5 3
Day 6 3
Day 7 3
它完全避免在@start 和@end 之间的每一天使用递归CTE 和DATEADD。这只是一些数学运算。
对于多个日期,您也可以使用类似的方法,尽管它在大范围内效率不高:
declare @start date = '20151001', @end date = '20151017'
Select DATEADD(DAY, n, @start), DATEPART(WEEKDAY, DATEADD(DAY, n, @start))
From (
Select top(DATEDIFF(DAY, @start, @end)+1) ROW_NUMBER() over(order by n)-1
From (
Select 1 From (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as v1(n)
Cross Join (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as v2(n)
Cross Join (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as v3(n)
) as v(n)
) as o(n)
Where DATEPART(WEEKDAY, DATEADD(DAY, n, @start)) in (7, 1)
输出:
DATE WEEKDAY
2015-10-03 7
2015-10-04 1
2015-10-10 7
2015-10-11 1
2015-10-17 7
这里,7 = 星期六,1 = 星期日。您可以添加 1 到 7 之间的任何值,或者它可以来自另一个表。
如果您使用 DATENAME,则可以将其替换为日期名称。
然后,您只需添加一个分组依据和/或一个总和即可获得周六和周日的数量。
V1/V2/V3 避免使用递归查询并快速生成从 0 到 X(最多 999)的数字列表。 X 是 @start 和 @end 之间的天数之差。如果您需要 10.000 天范围(等等...),请添加 v4,但 1000 天足够使用 2 年以上,差不多 3 年。