0

我只是在玩 cte 打印 1 到 10 或打印 12 个月

create table eventlist 
  (
    id int identity(1,1) not null, 
    edate smalldatetime 
  )
  select * from eventlist

  insert into eventlist select '01/01/2012'




  ;with cte AS
    (
       select edate from eventlist 
       union all 

       select dateadd(M,1,edate) from cte where MONTH(edate)<12


    )

    select MONTH(edate), YEAR (edate) from cte

但突然间,我只是像这样将 cte 中的另一个联合所有部分组合在一起

;with cte AS
    (
       select edate from eventlist 
       union all 

       select dateadd(M,1,edate) from cte where MONTH(edate)<12
       union all 
       select dateadd(Y,1,edate) from cte where YEAR(edate)<2013

    )

    select MONTH(edate), YEAR (edate) from cte

当我运行这个我会得到这个错误

声明终止。在语句完成之前,最大递归 100 已用完。

由于递归限制,我理解这个错误,但是 i just want to understand how will this recurssion will work ?

4

1 回答 1

1

Y是 DateOfYear 的缩写,而不是年份。尝试yy甚至yyyy更好的year.

你得到的错误是因为你超过了 recursion 限制。您要求 CTE 从日期 ( '2012-01-01') 开始,并且在每个(递归)步骤中,生成一个月后的第二天('2012-01-01'第一步)第二天('2012-01-02'第一步)。然后在第二步中,必须再生产 4 行,第一步生产的每行新行 2 行。然后是 8,然后是 16,依此类推(该条件MONTH(edate)<12仅在您在第 11 步中产生 2^10 新行之后才有效。即使那样,它也只会稍微限制后续步骤中产生的行数。您原来的如果没有递归限制,查询将创建数百万行)。

这就是为什么您的 CTE 不会像您期望的那样返回 24 行,而是返回 90 行(即使您更改YYear),因为双重递归。

用这个:

; with cte AS
(
   select edate from eventlist 
   union all 
   select dateadd(Month,1,edate) from cte where MONTH(edate)<12
)

, cte2 AS
(
   select edate from cte 
   union all 
   select dateadd(Year,1,edate) from cte2 where YEAR(edate)<2013
)

select MONTH(edate), YEAR(edate) from cte2 ;

或者我认为更简单的这个:

; with cte AS
(
   select edate from eventlist 
   union all 
   select dateadd(Month,1,edate) from cte where edate < '2013-12-01'
)

select MONTH(edate), YEAR(edate) from cte ;
于 2012-10-20T10:17:12.380 回答