我认为以下工作:
select t.*
from (select t.*,
row_number() over (partition by r.requestid, IsWorkDay order by seqdate) as WorkDayNum
from (select r.requestid, r.TransactionDate,
(case when critical = 1 then 5 else 10 end) as DaysToRespond,
dateadd(day, days.seqnum - 1, r.TransactionDate) as seqdate,
(case when h.date is null then 1 else 0 end) as IsWorkDay
from requests r cross join
(select top 20 ROW_NUMBER() over (order by (select NULL)) as seqnum
from information_schema.columns
) days left outer join
holidays h
on dateadd(day, days.seqnum - 1, r.TransactionDate) = h.date
) t
) t
where WorkDayNum = DaysToRespond and IsWorkDay = 1
这是未经测试的,但这是这个想法。
好吧,我已经对此进行了测试,在这种情况下它似乎返回了正确的结果:
with holidays as (
select CAST('2012-01-01' as date) as date union all
select CAST('2012-01-05' as date) as date union all
select CAST('2012-01-06' as date) as date union all
select CAST('2012-01-12' as date) as date union all
select CAST('2012-01-13' as date) as date union all
select CAST('2012-01-19' as date) as date union all
select CAST('2012-01-20' as date) as date
),
requests as (
select 1 as requestId, CAST('2012-01-02' as DATE) as TransactionDate, 1 as Critical
)
select t.*
from (select t.*,
row_number() over (partition by t.requestid, IsWorkDay order by seqdate) as WorkDayNum
from (select r.requestid, r.TransactionDate,
(case when critical = 1 then 5 else 10 end) as DaysToRespond,
dateadd(day, days.seqnum - 1, r.TransactionDate) as seqdate,
(case when h.date is null then 1 else 0 end) as IsWorkDay
from requests r cross join
(select top 20 ROW_NUMBER() over (order by (select NULL)) as seqnum
from INFORMATION_SCHEMA.columns
) days left outer join
holidays h
on dateadd(day, days.seqnum - 1, r.TransactionDate) = h.date
) t
) t
where WorkDayNum = DaysToRespond+1 and IsWorkDay = 1
此查询创建交易日期后 20 天的序列(20 天够吗?)。然后它计算这些天的日期并将日期与假期表进行比较。
计算天数是使用row_number()
按请求和工作日与非工作日进行分区。要选择的行是工作日和交易日期之后的天数。