如何在多条记录上使用CTE

时间:2017-08-24 17:09:24

标签: sql sql-server

我有一个像这样的日期表:

Exit_Date     Date_ID
2017-05-31     1
2017-04-26     2
2017-01-02     3
2016-12-24     4
2016-11-27     5

我使用循环将每个日期插入CTE,以生成这些日期的最后15年:

declare @DI int = 1
declare @d date
while @DI <=5
begin
select @d = Exit_Date from Date_Table where Date_ID = @DI
declare @EDTable table (Exit_Date  Date);
with
  a as(
    select dateadd(yy,-1,@d) d,0 i
      union all
    select dateadd(yy,-1,d),i+1 from a where i<14
  ),
  b as(select d,datediff(dd,0,d)%7 dd from a)
 insert into @EDTable select d from b;
  set @DI = @DI + 1
 end

结果是正确的,我的日期得到75行。我想知道是否有办法通过将Date_Table中的每个日期记录替换变量WHILE来摆脱@d循环?

2 个答案:

答案 0 :(得分:0)

你可以用数字表替换你的循环,或者像这样用adhoc数字表替换:

;with numbers as (
  select top (15)
    i = row_number() over (order by (select 1))
  from [master]..spt_values
)
select Exit_Date = dateadd(year,-1*i,d.Exit_Date)
from Date_Table d
  cross join numbers n
where d.Date_id >= 1
  and d.Date_id <= 5

rextester演示:http://rextester.com/AQEZ43941

<小时/> 此方法优于递归解决方案,尤其是当行数增加时。

参考:

答案 1 :(得分:0)

只需使用递归CTE中的表:

create table #DateTable (
    Date_ID int primary key not null,
    Exit_Date date not null
);

insert into #DateTable (Exit_Date, Date_ID) values
('2017-05-31',1),
('2017-04-26',2),
('2017-01-02',3),
('2016-12-24',4),
('2016-11-27',5);

declare @EDTable table (Exit_Date  Date);

;with a as (
    select dateadd(yy,-1,Exit_Date) d,0 i from #DateTable where Date_ID between 1 and 5
    union all
    select dateadd(yy,-1,d),i+1 from a where i<14
)
,b as (
    select d,datediff(dd,0,d)%7 dd from a
)
insert into @EDTable
select d from b;