向后计划排除假期

时间:2017-11-14 00:14:18

标签: sql-server tsql

我的系统中有后向调度。我使用下面显示的功能排除周末或将日期推回到星期五,如果在周末放置了后退计划,但如何排除假期?例如,我想在假期后或2017年11月23日和24日推出任何日期。

这是我用来跳过周末的代码

Create function [dbo].[PreviousWorkDay]( @date date ) returns date as
begin
  set @date = dateadd( day, -1, @date )
  return
  (
    select case datepart( weekday, @date )
      when 7 then dateadd( day, -1, @date )
      when 1 then dateadd( day, -2, @date )
      else @date
    end
  )
end 

1 个答案:

答案 0 :(得分:1)

为了达到这个目的,你必须要做几件事。

1)创建基础设施以列出哪些日期被视为假期。这有两个原因是必要的:A)每年有一些假期(例如感恩节),B)假期不是工作日取决于组织。

2)就像HABO所说的那样,删除您对datepart / weekday的依赖,因为有人可能会更改您实例上的此设置,而您现有的逻辑会变得混乱。

假日基础设施

create table dbo.holidays
    (
        holiday_dt date not null
    )

insert into dbo.holidays
values ('2017-11-23') --Thanksgiving (moves every year)
    , ('2017-12-25') --Christmas (same day every year)

<强>答案

create function [dbo].[PreviousWorkDay]( @date date ) returns date as
begin

    declare @date_rng int = 7 --dont think there would ever be 7 holiday/weekend days in a row
        , @ans date;

    with date_list as
        (
            --use a Recursive CTE to generate a list of recent dates (assuming there is no table w/ each calendar day listed)
            select dateadd(d, -1*@date_rng, @date) as dt
            union all
            select dateadd(d,1,dt) as dt
            from date_list
            where 1=1
            and dt < @date
        )
    select @ans = max(sub.dt)
    from (
        select dl.dt
        , case when datename(dw, dl.dt) in ('Saturday', 'Sunday') then 0
               when h.holiday_dt is not null then 0
               else 1
          end as is_work_day
        from date_list as dl
        left join dbo.holidays as h on dl.dt = h.holiday_dt
        ) as sub
    where 1=1
    and sub.is_work_day = 1

    return @ans;

end

go

示例

此函数调用

  select dbo.PreviousWorkDay('2017-12-25')

会返回2017-12-22