从 table 获取所有子节点
Get all child nodes from table
我正在尝试从 table 获取所有子节点,但我的查询获取了一些额外的结果,我不确定为什么
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]
当运行这个查询时,我正在获取其他子节点
注意* 在我的 VB.Net 应用程序中(需要调用此 SQL 的地方)0 的 ParentID 是树视图中的根节点。
Table
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
结果
pkID | parentID | CategoryName
6 | 0 | Category6
1 | 6 | Category1
9 | 7 | Category9 <-- not a child of pkID=6
因为tblcategory
WHERE [pkID] = 6
底部select 需要相同的where 语句。没有它,您将获得整个 table.
的 children
所以这样的事情应该可行:
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
如 Juan 所说的那样简化了,我应该想到可以在同一个 select 语句中作为单个 where 条件来完成。
SELECT [pkID]
,[parentID]
,[CategoryName]
FROM [tblCategory]
WHERE [pkID] = 6
or ParentId = 6
这是一个递归的 cte 方法,用于获取 parentid 的所有 children、grand children、great grand children 等。
;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
看起来你想做一个递归的 cte,但后来你改变了主意。
该查询可以简化为
SELECT [pkID]
,[parentID]
,[CategoryName]
FROM [tblCategory]
WHERE [pkID] = 6
OR [ParentID] = 6
假设第二个节点也可能有子节点,我建议使用递归查询。像这样(未经测试):
DECLARE @SearchID int = 6;
WITH cteTree AS(
SELECT pkID, parentID, CategoryName
FROM tblCategory
WHERE pkID = @SearchID
UNION ALL
SELECT pt.pkID, pt.parentID, pt.CategoryName
FROM tblCategory AS pt
JOIN cteTree AS ct ON ct.pkID = pt.parentID
)
SELECT *
FROM cteTree
我正在尝试从 table 获取所有子节点,但我的查询获取了一些额外的结果,我不确定为什么
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]
当运行这个查询时,我正在获取其他子节点 注意* 在我的 VB.Net 应用程序中(需要调用此 SQL 的地方)0 的 ParentID 是树视图中的根节点。
Table
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
结果
pkID | parentID | CategoryName
6 | 0 | Category6
1 | 6 | Category1
9 | 7 | Category9 <-- not a child of pkID=6
因为tblcategory
WHERE [pkID] = 6
底部select 需要相同的where 语句。没有它,您将获得整个 table.
所以这样的事情应该可行:
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
如 Juan 所说的那样简化了,我应该想到可以在同一个 select 语句中作为单个 where 条件来完成。
SELECT [pkID]
,[parentID]
,[CategoryName]
FROM [tblCategory]
WHERE [pkID] = 6
or ParentId = 6
这是一个递归的 cte 方法,用于获取 parentid 的所有 children、grand children、great grand children 等。
;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
看起来你想做一个递归的 cte,但后来你改变了主意。
该查询可以简化为
SELECT [pkID]
,[parentID]
,[CategoryName]
FROM [tblCategory]
WHERE [pkID] = 6
OR [ParentID] = 6
假设第二个节点也可能有子节点,我建议使用递归查询。像这样(未经测试):
DECLARE @SearchID int = 6;
WITH cteTree AS(
SELECT pkID, parentID, CategoryName
FROM tblCategory
WHERE pkID = @SearchID
UNION ALL
SELECT pt.pkID, pt.parentID, pt.CategoryName
FROM tblCategory AS pt
JOIN cteTree AS ct ON ct.pkID = pt.parentID
)
SELECT *
FROM cteTree