2017-08-24 104 views
1

我有一個日期表這樣一個使用CTE:如何在多個記錄

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中的每個日期記錄替換變量@d來擺脫WHILE循環?

+3

如果您的工作代碼已經產生了您想要的結果,但正在尋求改進,這可能更適合於Code Review而不是Stack Overflow。 –

+0

@Damien_The_Unbeliever謝謝我不知道代碼審查的存在 – JulGreen

+0

看看CROSS APPLY消除循環 –

回答

0

您可以用數字替換表中的循環,或即興數字表所示:

;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


這種方法優於遞歸的解決方案,尤其是作爲行增加數。

參考:

+0

非常感謝你 – JulGreen

+0

@JulGreen樂於幫忙! – SqlZim

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;