You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归CTE使用UNION ALL为何未返回重复数据?

为什么递归SQL返回的日期没有重复?

哈哈,你这是对递归CTE的执行逻辑产生了一个非常典型的误解!我来给你掰扯清楚:

首先,先还原一下你大概率用到的那种递归日期SQL(毕竟这是生成连续日期的经典写法):

WITH DateCTE AS (
    -- 锚点成员:初始日期
    SELECT CAST('2011-09-01' AS DATE) AS dt
    UNION ALL
    -- 递归成员:基于上一次结果生成下一个日期
    SELECT DATEADD(day, 1, dt) 
    FROM DateCTE
    WHERE dt < CAST('2011-10-01' AS DATE)
)
SELECT dt FROM DateCTE;

你之前的认知是:每次递归迭代都会把所有已生成的日期都加1,然后和之前的集合做UNION ALL,这样会出现大量重复——但这完全搞错了递归CTE的工作方式!

递归CTE的执行是严格分阶段的:

  • 第一步:执行锚点成员:只运行一次,得到初始结果集(这里就是2011-09-01这一行)。
  • 第二步:递归迭代:每一次递归,只会针对上一轮递归输出的结果集进行计算,而不是整个历史所有行。

拿这个例子一步步看:

  1. 第一次递归:只处理锚点的2011-09-01,加1天得到2011-09-02,和锚点结果UNION ALL后,集合是[2011-09-01, 2011-09-02]。
  2. 第二次递归:只处理上一轮返回的2011-09-02,加1得到2011-09-03,UNION ALL后集合变成[2011-09-01, 2011-09-02, 2011-09-03]。
  3. 以此类推,每一轮只会新增一个全新的日期,直到递归成员生成的日期触达2011-10-01,WHERE条件不满足,递归终止。

所以最终结果自然是从2011-09-01到2011-10-01的所有唯一日期,完全不会有重复。

如果真的要得到你预期的重复数据,那得换写法——比如每次都基于锚点成员来生成新行,但那已经不是递归CTE的常规用法啦。

内容的提问来源于stack exchange,提问作者Shawn Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:05:51