首页 > 解决方案 > 递归CTE的逻辑处理

问题描述

我不明白为什么当递归成员调用 cte 时没有调用锚点。

为什么它会转到递归部分的最新记录(?)?

WITH Managers AS 
( 
--initialization 
SELECT EmployeeID, LastName, ReportsTo  
FROM Employees 
WHERE ReportsTo IS NULL 
UNION ALL 
--recursive execution 
SELECT e.employeeID,e.LastName, e.ReportsTo 
FROM Employees e INNER JOIN Managers m  
ON e.ReportsTo = m.employeeID 
) 
SELECT * FROM Managers

标签: sqlsql-servertsqlcommon-table-expressionrecursive-query

解决方案


这是著名的 Microsoft 示例数据库Northwind(自 1997 年以来不可变)。该Emploeees表演示了分层数据和使用递归 CTE(1997 年不可用)来访问它。

为了更好地理解/测试/培训目的,添加一个额外的列

WITH Managers AS 
( 
  --initialization 
  SELECT EmployeeID, LastName, ReportsTo, /*extra column*/ 0 [level]  
  FROM Employees 
  WHERE ReportsTo IS NULL 

  UNION ALL 

  --recursive execution 
  SELECT e.employeeID,e.LastName, e.ReportsTo, [level]+1 
  FROM Employees e 
  INNER JOIN Managers m ON e.ReportsTo = m.employeeID 
) 
SELECT * FROM Managers

这是结果集。

EmployeeID  LastName             ReportsTo   level
----------- -------------------- ----------- -----------
2           Fuller               NULL        0 --anchor call
--now 'Managers' CTE is the anchor (level 0)
1           Davolio              2           1
3           Leverling            2           1
4           Peacock              2           1
5           Buchanan             2           1
8           Callahan             2           1
--now 'Managers' CTE is resultset level 1
6           Suyama               5           2
7           King                 5           2
9           Dodsworth            5           2

所以总是执行,如果锚返回行,递归部分就会执行。


推荐阅读