我的系统中有后向调度。我使用下面显示的功能排除周末或将日期推回到星期五,如果在周末放置了后退计划,但如何排除假期?例如,我想在假期后或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
答案 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
。