sql >> データベース >  >> RDS >> Sqlserver

T-SQLは、2つの日付の間の稼働日数を取得します

    どうぞ、カレンダーテーブルをご利用ください。 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を設定してください 適切に設定...



    1. PostgreSQLの監査ログ

    2. ファイルシステムではなくデータベースにファイルを保存しますか?

    3. Postgresql GROUP_CONCATと同等ですか?

    4. MySQL CRC32()関数–例