从表中获取所有子节点

Ale*_*lex 0 sql parent-child

我正在尝试从表中获取所有子节点,但是我的查询正在获取一些额外的结果,我不确定为什么

SELECT [pkID]
    ,[parentID]
    ,[CategoryName]
FROM [tblCategory]
WHERE [pkID] = 6
UNION ALL
SELECT [Sub].[pkID]
    ,[Sub].[ParentID]
    ,[Sub].[CategoryName]
FROM [tblCategory] [Sub]
INNER JOIN [tblCategory] AS [Sub2] ON [Sub].[ParentID] = [Sub2].[pkID]
Run Code Online (Sandbox Code Playgroud)

运行此查询时,我将获得其他子节点注意*在我的VB.Net应用程序中(需要调用此SQL的地方),ParentID为0是树视图中的根节点。

pkID | ParentID | CategoryName
1    | 6        | Category1
2    | 0        | Category2
3    | 0        | Category3
4    | 0        | Category4
5    | 0        | Category5
6    | 0        | Category6
7    | 0        | Category7
8    | 0        | Category8
9    | 7        | Category9
Run Code Online (Sandbox Code Playgroud)

结果

pkID | parentID | CategoryName
6    | 0        | Category6
1    | 6        | Category1
9    | 7        | Category9 <-- not a child of pkID=6
Run Code Online (Sandbox Code Playgroud)

Mat*_*att 5

这是因为您需要在底部选择相同的where语句tblcategory WHERE [pkID] = 6。有了它,您就会得到整个桌子的孩子。

所以这样的事情应该工作:

SELECT [pkID]
    ,[parentID]
    ,[CategoryName]
FROM [tblCategory]
WHERE [pkID] = 6
UNION ALL
SELECT [Sub].[pkID]
    ,[Sub].[ParentID]
    ,[Sub].[CategoryName]
FROM [tblCategory] [Sub]
INNER JOIN [tblCategory] AS [Sub2] ON [Sub].[ParentID] = [Sub2].[pkID]
WHERE [sub].[pkID] = 6
Run Code Online (Sandbox Code Playgroud)

正如Juan所说的那样简化,我应该想到可以在同一select语句上的单个where条件下完成。

SELECT [pkID]
    ,[parentID]
    ,[CategoryName]
FROM [tblCategory]
WHERE [pkID] = 6
     or ParentId = 6
Run Code Online (Sandbox Code Playgroud)

这是一种递归cte方法,用于获取父对象的所有子代,孙子代,曾孙子等。

;WITH cte AS (
    SELECT [pkID]
       ,[parentID]
       ,[CategoryName]
       -- ,1 AS [Level]
    FROM [tblCategory]
    WHERE [pkID] = 6


    UNION ALL

    SELECT
       t.pkId
       ,t.[parentID]
       ,t.CategoryName
       -- ,[Level] + 1 AS [Level]
    FROM
       [tblCategory] t
       INNER JOIN cte c
       ON t.ParentId = c.pkId
)

SELECT *
FROM cte  
Run Code Online (Sandbox Code Playgroud)