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

営業時間と休日から期日を計算する

    有効な営業時間と、週末と祝日を除外した (またはスキップできるように週末/祝日としてマークされた) テーブルが必要です。各行は 1 日とその日の労働時間数を表します。次に、開始日から、マークされた週末/休日の行を除いて、sum(hours*60) が minutes パラメーターよりも大きい最初の (min) 日まで、営業時間テーブルをクエリします。これで終了日が決まります。

    これがその日のテーブルです:

    CREATE TABLE [dbo].[tblDay](
        [dt] [datetime] NOT NULL,
        [dayOfWk] [int] NULL,
        [dayOfWkInMo] [int] NULL,
        [isWeekend] [bit] NOT NULL,
        [holidayID] [int] NULL,
        [workingDayCount] [int] NULL,
     CONSTRAINT [PK_tblDay] PRIMARY KEY CLUSTERED 
    (
        [dt] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    

    テーブルに日数を入力する方法は次のとおりです:

    CREATE PROCEDURE [dbo].[usp_tblDay]
    AS
    BEGIN
        SET NOCOUNT ON;
        DECLARE  
            @Dt datetime ,
            @wkInMo int,
            @firstDwOfMo int,
            @holID int,
            @workDayCount int,
            @weekday int,
            @month int,
            @day int,
            @isWkEnd bit
    
        set @workDayCount = 0
        SET @Dt = CONVERT( datetime, '2008-01-01' ) 
        while @dt < '2020-01-01'
        begin
            delete from tblDay where dt = @dt
    
            set @weekday = datepart( weekday, @Dt )
            set @month = datepart(month,@dt)
            set @day = datepart(day,@dt)
    
            if @day = 1  -- 1st of mo
                begin
                    set @wkInMo = 1
                    set @firstDwOfMo = @weekday
                end
    
            if ((@weekday = 7) or (@weekday = 1)) 
                set @isWkEnd = 1 
            else 
                set @isWkEnd = 0
    
            if @isWkEnd = 0 and (@month = 1 and @day = 1) 
                set @holID=1        -- new years on workday
            else if @weekday= 6 and (@month = 12 and @day = 31) 
                set @holID=1        -- holiday on sat, change to fri
            else if @weekday= 2 and (@month = 1 and @day = 2) 
                set @holID=1        -- holiday on sun, change to mon
    
            else if @wkInMo = 3 and @weekday= 2 and @month = 1 
                set @holID = 2      -- mlk
    
            else if @wkInMo = 3 and @weekday= 2 and @month = 2 
                set @holID = 3      -- President’s
    
            else if @wkInMo = 4 and @weekday= 2 and @month = 5 and datepart(month,@dt+7) = 6
                set @holID = 4      -- memorial on 4th mon, no 5th
            else if @wkInMo = 5 and @weekday= 2 and @month = 5 
                set @holID = 4      -- memorial on 5th mon
    
            else if @isWkEnd = 0 and (@month = 7 and @day = 4) 
                set @holID=5        -- July 4 on workday
            else if @weekday= 6 and (@month = 7 and @day = 3) 
                set @holID=5        -- holiday on sat, change to fri
            else if @weekday= 2 and (@month = 7 and @day = 5) 
                set @holID=5        -- holiday on sun, change to mon
    
            else if @wkInMo = 1 and @weekday= 2 and @month = 9 
                set @holID = 6      -- Labor
    
            else if @isWkEnd = 0 and (@month = 11 and @day = 11) 
                set @holID=7        -- Vets day on workday
            else if @weekday= 6 and (@month = 11 and @day = 10) 
                set @holID=7        -- holiday on sat, change to fri
            else if @weekday= 2 and (@month = 11 and @day = 12) 
                set @holID=7        -- holiday on sun, change to mon
    
            else if @wkInMo = 4 and @weekday= 5 and @month = 11 
                set @holID = 8      -- thx
    
            else if @holID = 8
                set @holID = 9      -- dy after thx
    
            else if @isWkEnd = 0 and (@month = 12 and @day = 25) 
                set @holID=10       -- xmas day on workday
            else if @weekday= 6 and (@month = 12 and @day = 24) 
                set @holID=10       -- holiday on sat, change to fri
            else if @weekday= 2 and (@month = 12 and @day = 26) 
                set @holID=10       -- holiday on sun, change to mon
            else
                set @holID = null
    
            insert into tblDay select @dt,@weekday,@wkInMo,@isWkEnd,@holID,@workDayCount
    
            if @isWkEnd=0 and @holID is null 
                set @workDayCount = @workDayCount + 1
    
            set @dt = @dt + 1
            if datepart( weekday, @Dt ) = @firstDwOfMo 
                set @wkInMo = @wkInMo + 1
        end
    END
    

    休日のテーブルもありますが、休日は人それぞれです:

    holidayID   holiday rule description
    1   New Year's Day  Jan. 1
    2   Martin Luther King Day  third Mon. in Jan.
    3   Presidents' Day third Mon. in Feb.
    4   Memorial Day    last Mon. in May
    5   Independence Day    4-Jul
    6   Labor Day   first Mon. in Sept
    7   Veterans' Day   Nov. 11
    8   Thanksgiving    fourth Thurs. in Nov.
    9   Fri after Thanksgiving  Friday after Thanksgiving
    10  Christmas Day   Dec. 25
    

    HTH



    1. 分割後のSQLソート数値文字列

    2. EntityFramework6の動的MySQLデータベース接続

    3. SCDタイプ3

    4. MySQLインデックス-いくつで十分ですか?