SQL Server中的递归查询问题

时间:2013-01-26 18:46:48

标签: sql sql-server sql-server-2008 tsql sql-server-2012

我在SQL Server中遇到递归查询问题。

假设我有2个表:

  1. Holiday:此表存储所有假期(holidayDate非工作日)
  2. Invoice:此表存储下一个付款日期(nextPaymentDate
  3. 如果nextPaymentDate位于假期表中的holidayDate,那么我需要更新它:

    nextPaymentDate = nextPaymentDate + 1 day
    

    此步骤需要处理,直到nextPaymentDate不再holidayDate为止。

    请参阅下面的示例数据示例:

    Holiday表:

    HolidyaID      HolidayDate
    -----------------------------
       1           2012-01-02
       2           2012-01-03
       3           2012-01-04
       4           2012-01-08
       5           2012-01-12
       6           2012-01-13
       7           2012-01-20
       8           2012-01-21
       9           2012-01-22
       10          2012-01-23
       11          2012-01-29
       12          2012-01-30
    

    Invoice

    InvoiceID      NextPaymentDate
    ------------------------------
       1           2012-01-01
       2           2012-01-02
       3           2012-01-09
       4           2012-01-20
    

    运行此查询后,我希望在Invoice表格中看到这样的数据

    InvoiceID      NextPaymentDate
    -------------------------------
       1               2012-01-01
       2               2012-01-05
       3               2012-01-09
       4               2012-01-24
    

    如何创建SQL查询以输出此结果?

    您可以在http://sqlfiddle.com/#!6/de346/3

    测试此查询

    谢谢!

3 个答案:

答案 0 :(得分:0)

select InvoiceID,
Case when [holidaydate] is null then [NextPaymnetDate]
else
DateAdd(dd,1,
(Select min([holidaydate]) from holiday h
where  h.[holidaydate]>[NextPaymnetDate]
and not exists(Select * from holiday h2 where h2.[holidaydate]=DateAdd(dd,1,h.[holidaydate])) 
))
end
from invoice
left Join holiday on [holidaydate]=[NextPaymnetDate]

答案 1 :(得分:0)

with holidayBatch as
(
  select workingdate = dateadd(dd, 1, holidayDate)
  from Holiday h
  where not exists (select 1 from Holiday nxt
                    where nxt.holidaydate = dateadd(dd, 1, h.holidaydate))
)
select i.invoiceid,
  case when h.holidaydate is null then i.NextPaymentDate else hb.workingdate end
from Invoice i
  left join Holiday h on i.NextPaymentDate = h.holidaydate
  outer apply (select top 1 workingdate
              from holidayBatch hb where workingdate > NextPaymentDate
              order by workingdate) hb
order by i.invoiceid

SQL Fiddle

答案 2 :(得分:0)

    select invoiceid, coalesce(nd,NextPaymnetDate) dd from invoice i left join
    (
    select *,(select min(dateADD(dd,1,holidaydate)) from holiday 
where holidaydate>=h.holidaydate and 
dateADD(dd,1,holidaydate) not in (select holidaydate from holiday)) nd 
    from holiday h) h on NextPaymnetDate = holidaydate;