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

SQL递归CTE递归成员循环及Rank计算逻辑疑问

递归CTE运行原理解答

你对锚成员的初始判断是对的:递归CTE第一次执行时,锚成员确实只会返回ManagerID IS NULL的最高级员工行,Rank值为1。你疑惑的点本质是对递归成员的循环执行规则不清晰,核心逻辑如下:

  • 递归CTE的递归成员不是只执行一次,而是会循环触发,每次执行时用来关联的EmployeesCTE不是整个CTE的累计结果,仅为上一轮递归新产出的结果集。
  • 每轮递归的产出结果,会同时做两个操作:一是追加到整个CTE的最终结果集里,二是作为下一轮递归时EmployeesCTE的关联数据。

我们可以用实际执行步骤拆解验证:

  1. 第一轮执行锚成员,得到结果集R1:仅最高级领导,Rank=1。R1追加到CTE最终结果,同时作为下一轮的输入。
  2. 第二轮执行递归成员,拿R1和Employees表做关联,匹配条件是Employees.ManagerID = R1.EmployeeID,得到的是最高级领导的所有直接下属,Rank为R1的Rank+1=2,产出结果集R2。R2追加到CTE最终结果,作为下一轮输入。
  3. 第三轮执行递归成员,拿R2和Employees表关联,得到R2里所有员工的直接下属,Rank为2+1=3,产出结果集R3,追加到最终结果,交给下一轮。
  4. 循环执行以上逻辑,直到某一轮递归执行后没有返回任何行,递归终止。

这个逻辑下不会出现你担心的错误增量问题:因为每轮递归只会处理上一轮新产生的上级员工,只会给这些上级的直接下属计算Rank增量,不会重复处理已经计算过的历史员工行。
你贴的SQL执行后就会返回全公司员工的层级树,Rank值对应员工的组织层级,Rank=1是最高负责人,Rank=2是一级部门负责人,以此类推。

USE Examples;

WITH EmployeesCTE AS
(
    -- 锚成员:获取最高级负责人
    SELECT EmployeeID, 
        FirstName + ' ' + LastName As EmployeeName, 
        1 As Rank
    FROM Employees
    WHERE ManagerID IS NULL
UNION ALL
    -- 递归成员:逐层级获取下属
    SELECT Employees.EmployeeID, 
        FirstName + ' ' + LastName, 
        Rank + 1
    FROM Employees
        JOIN EmployeesCTE
        ON Employees.ManagerID = EmployeesCTE.EmployeeID
)
SELECT *
FROM EmployeesCTE
ORDER BY Rank, EmployeeID;

SELECT * 
FROM Employees

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 04:09:05