Alsjeblieft, alsjeblieft, gebruik alsjeblieft een kalendertabel. SQL Server weet niets over nationale feestdagen, bedrijfsevenementen, natuurrampen, enz. Een kalendertabel is vrij eenvoudig te maken, neemt extreem weinig ruimte in beslag en zal in het geheugen staan als er voldoende naar wordt verwezen.
Hier is een voorbeeld dat een kalendertabel maakt met datums van 30 jaar (2000 -> 2029), maar die slechts 200 KB op schijf vereist (136 KB als je paginacompressie gebruikt). Dat is bijna gegarandeerd minder dan de geheugentoelage die nodig is om een of andere CTE of andere set tijdens runtime te verwerken.
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 is de vraag die u zoekt vrij eenvoudig te schrijven:
SELECT COUNT(*) FROM dbo.Calendar
WHERE dt >= '20130110'
AND dt < '20130115'
AND IsWorkDay = 1;
Meer info over kalendertabellen:
http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html
Meer info over stroomaggregaten zonder lussen:
http://www.sqlperformance.com/tag/date-ranges
Pas ook op voor kleine dingen, zoals vertrouwen op de Engelse uitvoer van DATENAME
. Ik heb verschillende applicaties zien stukgaan omdat sommige gebruikers een andere taalinstelling hadden, en als je vertrouwt op WEEKDAY
zorg ervoor dat u uw DATEFIRST
. instelt juiste instelling...