Venligst, venligst, brug venligst en kalendertabel. SQL Server ved ikke noget om nationale helligdage, firmaarrangementer, naturkatastrofer osv. En kalendertabel er ret nem at bygge, tager meget lidt plads og vil være i hukommelsen, hvis der refereres nok til den.
Her er et eksempel, der opretter en kalendertabel med 30 års datoer (2000 -> 2029), men som kun kræver 200 KB på disk (136 KB hvis du bruger sidekomprimering). Det er næsten garanteret at være mindre end den hukommelsesbevilling, der kræves for at behandle et eller andet CTE-sæt under kørsel.
CREATE TABLE dbo.Calendar
(
dt DATE PRIMARY KEY, -- use SMALLDATETIME if < SQL Server 2008
IsWorkDay BIT
);
DECLARE @s DATE, @e DATE;
SELECT @s = '2000-01-01' , @e = '2029-12-31';
INSERT dbo.Calendar(dt, IsWorkDay)
SELECT DATEADD(DAY, n-1, '2000-01-01'), 1
FROM
(
SELECT TOP (DATEDIFF(DAY, @s, @e)+1) ROW_NUMBER()
OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
) AS x(n);
SET DATEFIRST 1;
-- weekends
UPDATE dbo.Calendar SET IsWorkDay = 0
WHERE DATEPART(WEEKDAY, dt) IN (6,7);
-- Christmas
UPDATE dbo.Calendar SET IsWorkDay = 0
WHERE MONTH(dt) = 12
AND DAY(dt) = 25
AND IsWorkDay = 1;
-- continue with other holidays, known company events, etc.
Nu er den forespørgsel, du leder efter, ret enkel at skrive:
SELECT COUNT(*) FROM dbo.Calendar
WHERE dt >= '20130110'
AND dt < '20130115'
AND IsWorkDay = 1;
Mere info om kalendertabeller:
http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html
Mere info om generatorsæt uden sløjfer:
http://www.sqlperformance.com/tag/date-ranges
Pas også på små ting som at stole på det engelske output af DATENAME
. Jeg har set flere applikationer gå i stykker, fordi nogle brugere havde en anden sprogindstilling, og hvis du stoler på WEEKDAY
sørg for at indstille din DATEFIRST
passende indstilling...