添加工作日到目前为止

时间:2017-04-26 13:23:36

标签: sql sql-server

在我构建一个可以在x个工作日后计算日期的函数的过程中,我遇到了这个函数:

ALTER FUNCTION [dbo].[AddBusinessDays] (@Date date,@n INT) 
RETURNS DATE AS BEGIN 
DECLARE @d INT;
SET @d=4-SIGN(@n)*(4-DATEPART(DW,@Date));
RETURN DATEADD(D,@n+((ABS(@n)+@d-2)/5)*2*SIGN(@n)-@d/7,@Date) END

此功能有效但我需要将其与我的假期表链接,以便它可以省略我所在国家/地区的特定假期。当我在今天的日期(26-04-2017)运行它时,我在24-05-2017之后的20个工作日内得到这个日期,所以它只省略了周末。如何修改它以便它也会跳过假期? 如果我发出一个问题请求太多,请道歉。我是SQL的初学者。谢谢

1 个答案:

答案 0 :(得分:0)

不是依赖于难以理解的计算,而是明确地确定工作日期并从中进行选择会更容易吗?例如:

DECLARE @NthWorkingDay INT = 33;

DECLARE @holidays TABLE
    (
      holiday DATE ,
      [description] VARCHAR(500)
    );
INSERT  @holidays
        ( holiday, description )
VALUES  ( '20170519', '...' ),
        ( '20170501', '...' ),
        ( '20170611', '...' ),
        ( '20170704', '...' );


DECLARE @sunday INT ,
    @saturday INT;
-- 1/1/2000 is a known date - Saturday

SET @saturday = DATEPART(WEEKDAY, DATEFROMPARTS(2000, 1, 1));
SET @sunday = DATEPART(WEEKDAY, DATEFROMPARTS(2000, 1, 2));

WITH    tally
          AS ( SELECT TOP 5000
                        ROW_NUMBER() OVER ( ORDER BY t1.object_id ) AS N
               FROM     master.sys.all_columns t1
                        CROSS JOIN master.sys.all_columns t2
             ),
        dates ( theDate )
          AS ( SELECT   DATEADD(DAY, N - 1, CAST(GETDATE() AS DATE))
               FROM     tally
             ),
        workDates ( workingDay, workingDate )
          AS ( SELECT   ROW_NUMBER() OVER ( ORDER BY theDate ) ,
                        theDate
               FROM     dates
               WHERE    DATEPART(WEEKDAY, theDate) NOT IN ( @saturday, @sunday )
                        AND theDate NOT IN ( SELECT holiday
                                             FROM   @holidays )
             )
    SELECT  workingDate
    FROM    workDates
    WHERE   workingDay = @NthWorkingDay;