私は次の作品だと思います:
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()
、リクエストによるパーティショニングと、稼働日と非稼働日を使用します。選択する行は、営業日であり、取引日からの日数です。