CTE递归查询的逻辑处理

时间:2013-01-25 07:51:52

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

此查询返回使用变量定义的日期范围之间的所有日期,结果集为31个不同的值。但是,递归CTE的工作方式是,第一个查询只执行一次,第二个查询适用于之前创建的结果集。所以,似乎会有重复,但它返回了不同的结果集。 CTE是否在内部应用DISTINCT子句还是其他的?我如何获得DISTINCT值?

DECLARE 
    @DateFrom DATE = '20130101' ,
    @DateTo DATE = '20130131'

WITH Days
AS ( SELECT CAST(@DateFrom AS DATETIME) AS dt
     UNION ALL
     SELECT DATEADD(dd, 1, dt)
     FROM Days s
     WHERE DATEADD(dd, 1, dt) <= CAST(@DateTo AS DATETIME)
   )

SELECT dt 
FROM Days

1 个答案:

答案 0 :(得分:1)

每次CTE递归时,它都会使用前一次递归产生的行(如果这是第一次递归,则使用初始行集)。

因此,对于您的查询,第一次运行会生成一行 - '20130101'转换为日期时间。

对于第一个递归步骤,我们获取最后一个递归或初始集('20130101')生成的所有行,并使用它生成一个新行,其中包含'20130102'

对于下一个递归步骤,我们获取最后一次递归('20130102')生成的所有行,并使用它生成一个新行('20130103'

对于下一个递归步骤,我们获取最后一次递归('20130103')生成的所有行,并使用它生成一个新行('20130104'

我没有看到任何会出现重复的地方。

了解更多here

  

递归执行的语义如下:

     
      
  1. 将CTE表达式拆分为锚点和递归成员。

  2.   
  3. 运行锚定成员创建第一个调用或基本结果集(T0)。

  4.   
  5. 运行递归成员,其中Ti为输入,Ti+1为输出。

  6.   
  7. 重复步骤3,直到返回空集。

  8.   
  9. 返回结果集。这是UNION ALL T0Tn

  10.