Per favore, per favore, per favore, usa una tabella del calendario. SQL Server non sa nulla di festività nazionali, eventi aziendali, disastri naturali e così via. Una tabella di calendario è abbastanza facile da creare, occupa una quantità estremamente ridotta di spazio e sarà in memoria se viene citata a sufficienza.
Ecco un esempio che crea una tabella calendario con 30 anni di date (2000 -> 2029) ma richiede solo 200 KB su disco (136 KB se usi la compressione della pagina). È quasi garantito che sia inferiore alla concessione di memoria richiesta per elaborare alcuni CTE o altri set in fase di esecuzione.
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.
Ora la query che stai cercando è abbastanza semplice da scrivere:
SELECT COUNT(*) FROM dbo.Calendar
WHERE dt >= '20130110'
AND dt < '20130115'
AND IsWorkDay = 1;
Maggiori informazioni sui tavoli del calendario:
http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html
Maggiori informazioni sui gruppi elettrogeni senza loop:
http://www.sqlperformance.com/tag/date-ranges
Fai attenzione anche a piccole cose come fare affidamento sull'output inglese di DATENAME
. Ho visto diverse applicazioni interrompersi perché alcuni utenti avevano un'impostazione della lingua diversa e se fai affidamento su WEEKDAY
assicurati di impostare il tuo DATEFIRST
impostazione appropriata...