伊诺夫:是的,这就是安多玛所说的——我正在做这件事,我想这需要窗口来工作@donviti,您正在运行哪个版本的SQL server?编译错误。当我将r.requestid替换为t.requestid并将holiday.date替换为h.date时,它返回一

伊诺夫:是的,这就是安多玛所说的——我正在做这件事,我想这需要窗口来工作@donviti,您正在运行哪个版本的SQL server?编译错误。当我将r.requestid替换为t.requestid并将holiday.date替换为h.date时,它返回一,sql,sql-server-2008,tsql,ssms,reporting-services,Sql,Sql Server 2008,Tsql,Ssms,Reporting Services,伊诺夫:是的,这就是安多玛所说的——我正在做这件事,我想这需要窗口来工作@donviti,您正在运行哪个版本的SQL server?编译错误。当我将r.requestid替换为t.requestid并将holiday.date替换为h.date时,它返回一个空行集。@Andomar。嗯,我已经测试过了。count(*)语法依赖于SQL Server 2012,因此我将其更改为row\u number()。而且,它确实有效。我将days子查询中的引用更改为information\u schema.



伊诺夫:是的,这就是安多玛所说的——我正在做这件事,我想这需要窗口来工作@donviti,您正在运行哪个版本的SQL server?编译错误。当我将
r.requestid
替换为
t.requestid
并将
holiday.date
替换为
h.date
时,它返回一个空行集。@Andomar。嗯,我已经测试过了。
count(*)
语法依赖于SQL Server 2012,因此我将其更改为
row\u number()
。而且,它确实有效。我将
days
子查询中的引用更改为
information\u schema.columns
而不是
holidays
。如果holidays表的行太少,那么它将无法工作。返回空行集?不知道我错过了什么。它被设置为SQL 2012。@Andomar。这是因为SQL FIDLE上的信息_Schema.Columns为空。这只是用来创建一个数字列表。您可以将其替换为
(选择1作为seqnum union all select 2 union all select 3…
。大多数数据库至少有几十列,因此这是编写更麻烦代码的捷径。只返回1行,日期非常遥远!编译错误。当我将
r.requestid
替换为
t.requestid
并将
holiday.date
替换为
h.date
时,它返回一个空行集。@Andomar。嗯,我已经测试过了。
count(*)
语法依赖于SQL Server 2012,因此我将其更改为
row\u number()
。而且,它确实有效。我将
days
子查询中的引用更改为
information\u schema.columns
而不是
holidays
。如果holidays表的行太少,那么它将无法工作。返回空行集?不知道我错过了什么。它被设置为SQL 2012。@Andomar。这是因为SQL FIDLE上的信息_Schema.Columns为空。这只是用来创建一个数字列表。您可以将其替换为
(选择1作为seqnum union all select 2 union all select 3…
。大多数数据库至少有几十列,因此这是编写更麻烦代码的捷径。只返回1行,日期非常遥远!你的和我的不同之处在于,我的假日表只包括有假日的日期,它不存储所有的日期。@Andromar,为什么你的第一次决斗日期是01-16?我的答案是01-15,我的数学似乎是正确的…@bluefoot:我的UDF只使用非工作日,但OP表中包含了所有天数。@PinnyM:AFAIK功能中的10个工作日意味着你可以在第11天交付。这10天是2,3,4,7,8,9,10,11,14,15,所以你在16号交货。@Andomar如果我仔细阅读这个问题,会很有帮助的。是时候删除我的答案了。:)你的和我的不同之处在于,我的假日表只包括有假日的日期,它不存储所有的日期。@Andromar,为什么你的第一次决斗日期是01-16?我的答案是01-15,我的数学似乎是正确的…@bluefoot:我的UDF只使用非工作日,但OP表中包含了所有天数。@PinnyM:AFAIK功能中的10个工作日意味着你可以在第11天交付。这10天是2,3,4,7,8,9,10,11,14,15,所以你在16号交货。@Andomar如果我仔细阅读这个问题,会很有帮助的。是时候删除我的答案了。:)
;WITH cte AS
(
   SELECT *,
         ROW_NUMBER() OVER (PARTITION BY id ORDER BY validDeliveryDate ASC) AS rn
   FROM (
       SELECT requests.*, holiday.Date as validDeliveryDate
       FROM requests
       JOIN holiday
         ON requests.TransactionDate < holiday.Date
         AND DATEADD(day, 25, requests.TransactionDate) >= holiday.Date
         AND holiday.BusinessDay = 'Y' ) v
)
SELECT *
FROM cte
WHERE rn = CASE WHEN critical = 1 THEN 5 ELSE 10 END
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
if exists (select * from sys.objects where name ='WorkingDaysFrom' and type = 'FN')
    drop function dbo.WorkingDaysFrom
go
create function dbo.WorkingDaysFrom(
        @date date
,       @days int)
returns date
as
begin
        declare @result date = @date
        declare @remaining int = @days
        while @remaining > 0
                begin
                set     @result = dateadd(day, @remaining, @result)
                select  @remaining = count(*) 
                from    dbo.Holiday 
                where   [Date] between dateadd(day, 1-@remaining, @result) and @result
                        and BusinessDay = 'N'
                end
        return @result
end
go
TransactionDate   Priority    DueDate
2013-01-01        Priority    2013-01-16
2013-01-01        Critical    2013-01-09
2013-01-03        Priority    2013-01-17
2013-01-03        Critical    2013-01-10
2013-01-06        Priority    2013-01-18
2013-01-06        Critical    2013-01-11