Have been pondering this and have come up with an alternative that uses a Tally table:
DECLARE @d1 datetime, @d2 datetime
SELECT
@d1 = '20090101',
@d2 = '20090331'
SELECT
count(N)
FROM
Tally
WHERE
N <= DATEDIFF(day,@d1,@d2)+1
AND
(DATEPART(dw,DATEADD(dd,n-1,@d1))+@@DATEFIRST)%7 BETWEEN 2 AND 6
Advantages over previous solutions, as I see it, are:
- Doesn't use CTE's (recursive or otherwise) or ROW_NUMBER, so can be used in SQL 2000.
- The query itself is a lot simpler to read
- Looking at the query plan 92% of the time is spent doing a clustered index seek.
- Use of @@DATEFIRST and Modulus operator makes the solution multi-culture
- Use of BETWEEN rather than NOT IN is significantly quicker