どうぞ、カレンダーテーブルをご利用ください。 SQL Serverは、国民の祝日、会社のイベント、自然災害などについて何も知りません。カレンダーテーブルは、作成が非常に簡単で、必要なスペースが非常に少なく、十分に参照されていればメモリに保存されます。
>これは、30年の日付(2000-> 2029)のカレンダーテーブルを作成する例ですが、ディスク上に必要なのは200 KB(ページ圧縮を使用する場合は136 KB)のみです。これは、実行時に一部のCTEまたはその他のセットを処理するために必要なメモリ許可よりも少ないことがほぼ保証されています。
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.
これで、必要なクエリを非常に簡単に作成できます。
SELECT COUNT(*) FROM dbo.Calendar
WHERE dt >= '20130110'
AND dt < '20130115'
AND IsWorkDay = 1;
カレンダーテーブルの詳細:
http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html
ループなしでセットを生成する方法の詳細:
http://www.sqlperformance.com/tag/date-ranges
また、DATENAME
の英語出力に依存するなどの小さなことに注意してください。 。一部のユーザーの言語設定が異なるため、またWEEKDAY
に依存している場合は、いくつかのアプリケーションが機能しなくなるのを目にしました。 必ずDATEFIRST
を設定してください 適切に設定...