Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
T-SQL递归CTE以查找最高的ParentID_Sql_Sql Server_Tsql - Fatal编程技术网

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

T-SQL递归CTE以查找最高的ParentID,sql,sql-server,tsql,Sql,Sql Server,Tsql,昨天的采访中,我被问到一个有趣的问题,那就是如何找到最高的 每行的ParentID 当时我无法回答这个问题,但我在网上找到了解决方案,但我仍然无法理解这个查询是如何工作的 有人能详细解释一下递归CTE是如何工作的吗?谢谢 我在按钮上发布了我提出的示例问题和解决方案 ================================================================= Create table dbo.##Test001 (ID int, Name varchar(10

昨天的采访中,我被问到一个有趣的问题,那就是如何找到最高的 每行的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 

提醒自己使用函数进行递归可能会有所帮助

-- pseudo code
void numberFunction(int i) {

  Print i

  increment i

  if(i<10) {
    numberFunction(i);
  }
}
递归公共表表达式CTE的结构为:

作为递归查询输入的锚查询 联合所有 递归查询-当递归查询返回空集时停止 请注意,在math/pseudo code函数中,我们增加或减少一个变量,并检查退出状态

在该查询中,当为匹配的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
然后将该输出与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可用于具有相同数量的参数和类似类型的查询

资料来源:

id  parentid    topParentID
1   NULL        1
5   NULL        5
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