我正在尝试从表中获取所有子节点,但我的查询正在获取一些额外的结果,我不知道为什么
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的地方)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
结果
pkID | parentID | CategoryName
6 | 0 | Category6
1 | 6 | Category1
9 | 7 | Category9 <-- not a child of pkID=6
答案 0 :(得分:5)
这是因为您需要在tblcategory
WHERE [pkID] = 6
的底部选择中使用相同的where语句。没有它你会得到整个桌子的孩子。
所以这样的事情应该有效:
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。
;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
答案 1 :(得分:1)
看起来你试图做一个递归的cte,但后来你改变主意。
该查询可以简化为
SELECT [pkID]
,[parentID]
,[CategoryName]
FROM [tblCategory]
WHERE [pkID] = 6
OR [ParentID] = 6
答案 2 :(得分:1)
假设第二个节点也可能有子节点,我建议使用递归查询。像这样(未经测试):
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