T-SQL递归CTE以查找最高的ParentID

时间:2014-08-13 21:12:15

标签: sql sql-server tsql

昨天的访谈我被问到一个有趣的问题,即如何找到最高的 每行的ParentID。

那时候我无法回答这个问题,但我在网上找到了解决方案,但我仍然无法理解这个查询的工作原理......

任何人都可以向我解释递归CTE的详细信息吗?感谢

我在按钮

上发布了我提出的示例问题和解决方案

=============================================== ==================

Create table dbo.##Test001 (ID int, Name varchar(100), ParentID int)

Insert into ##Test001 values (1, 'AA', null), (2, 'BB', 1), (3, 'CC', 2), (4, 'DD', 3)
,(5, 'AAA', null), (6, 'BBB', 5), (7, 'CCC', 6), (8, 'DDD', 7)



;WITH c AS (
SELECT id, parentid, id AS topParentID FROM   ##Test001 
WHERE  ParentID is null 

UNION ALL 

SELECT T.id, T.parentid, c.topparentid FROM   ##Test001 AS T 
INNER JOIN c 
ON T.parentid = c.id 
WHERE  T.id <> T.parentid
) 
SELECT id, topparentid FROM  c 
ORDER  BY id 

1 个答案:

答案 0 :(得分:2)

使用函数提醒自己可能会有所帮助。

-- pseudo code
void numberFunction(int i) {

  Print i

  increment i

  if(i<10) {
    numberFunction(i);
  }
}

或者,你可以手工完成更好的数学功能。

Fact (n) = n * fact (n-1) for n > 0

递归公用表表达式(CTE)的结构是:

  • 锚点查询(用作递归查询的输入)
  • UNION ALL
  • 递归查询 - 当递归查询返回空集
  • 时停止

注意在math / pseudo代码函数中,我们要么递增或递减变量,要检查退出状态。

在此查询中,当为匹配的T.parentid返回T.id时,递增/递减功能在递归查询中

此查询的退出状态是递归查询返回空集。

WITH c AS 
(
    SELECT 
        id, parentid, id AS topParentID 
    FROM   
        #Test001 
    WHERE  
        ParentID is null 

    UNION ALL 

    SELECT 
        T.id, T.parentid, c.topparentid 
    FROM   
        #Test001 AS T 
    INNER JOIN
        c ON T.parentid = c.id 
    WHERE  
        T.id <> T.parentid
) 
SELECT id, topparentid 
FROM c 
ORDER BY id

锚的输出建立最顶层的父级,并作为递归查询的输入。

id  parentid    topParentID
1   NULL        1
5   NULL        5

然后将此输出与T.parentid = c.id上的临时表#Test001 T连接。

ID  Name    ParentID
1   AA  NULL
2   BB  1
3   CC  2
4   DD  3
5   AAA NULL
6   BBB 5
7   CCC 6
8   DDD 7

SELECT T.id, T.parentid, c.topparentid 
FROM #Test001 AS T 
INNER JOIN c ON T.parentid = c.id 

T.id    T.parentid     c.topparentid
2       1              1
6       5              5

您可以继续执行剩余ID /父ID组合的过程。

UNION ALL结合了锚点查询和所有递归查询的所有结果。 UNION ALL可以与具有相同数量的参数和类似类型的查询一起使用。

来源:Recursive Queries Using CTE

Assembly Recursion