递归查询 SQL 服务器未按预期工作
Recursive query SQL Server not working as expected
在此先感谢您的帮助。我对 MS SQL db 还是很陌生,但我想知道为什么我对下面的 MSSQL 的递归查询没有 return 我期望的值。我已经完成了研究,底部是我想出的代码。假设我有以下 table...
CategoryID ParentID SomeName
1 0 hmm
2 0 err
3 0 woo
4 3 ppp
5 4 ttt
我期待下面的查询 return 3 4 5。我基本上想根据我在递归查询中传递的类别 ID,获取其下方的类别 ID 层次结构列表。感谢您的协助。
GO
WITH RecursiveQuery (CategoryID)
AS
(
-- Anchor member definition
SELECT a.CategoryID
FROM [SomeDB].[dbo].[SomeTable] AS a
WHERE a.ParentID = CategoryID
UNION ALL
-- Recursive member definition
SELECT b.CategoryID
FROM [SomeDB].[dbo].[SomeTable] AS b
INNER JOIN RecursiveQuery AS d
ON d.CategoryID = b.ParentID
)
-- Statement that executes the CTE
SELECT o.CategoryID
FROM [SomeDB].[dbo].[SomeTable] AS o
INNER JOIN RecursiveQuery AS d
ON d.CategoryID = 3
GO
如果你想要来自特定根的树:
DECLARE @rootCatID int = 3
;WITH LessonsTree (CatID)
AS
(
SELECT a.CategoryID
FROM [EducationDatabase].[dbo].[LessonCategory] AS a
WHERE a.CategoryID = @rootCatID ---<<<
UNION ALL
SELECT b.CategoryID
FROM LessonsTree as t
INNER JOIN [EducationDatabase].[dbo].[LessonCategory] AS b
ON b.ParentID = t.CatID
)
SELECT o.*
FROM LessonsTree t
INNER JOIN [EducationDatabase].[dbo].[LessonCategory] AS o
ON o.CategoryID = t.CatID
如评论中所述,锚点不受限制。最简单的解决方案是在锚点中添加标准
with RecursiveQuery (theID)
AS
(
SELECT a.ParentID --root id=parentid to include it and to prevent an extra trip to LessonCategory afterwards
FROM [LessonCategory] AS a
WHERE a.ParentID = 3 --restriction here
UNION ALL
SELECT b.CategoryID
FROM [LessonCategory] AS b
INNER JOIN RecursiveQuery AS d
ON d.theID = b.ParentID
)
SELECT* from RecursiveQuery
另一种选择是使递归查询具有通用性(无限制锚点)并保留 rootid。然后cte上的查询可以限制rootid(第一个选项可能更好,第二个主要适用于创建某种root-view的情况)
with RecursiveQuery
AS
(
SELECT a.ParentID theID, a.ParentID RootID
FROM [LessonCategory] AS a
UNION ALL
SELECT b.CategoryID, d.RootID
FROM [LessonCategory] AS b
INNER JOIN RecursiveQuery AS d
ON d.theID = b.ParentID
)
SELECT theID from RecursiveQuery where RootID = 3
在此先感谢您的帮助。我对 MS SQL db 还是很陌生,但我想知道为什么我对下面的 MSSQL 的递归查询没有 return 我期望的值。我已经完成了研究,底部是我想出的代码。假设我有以下 table...
CategoryID ParentID SomeName
1 0 hmm
2 0 err
3 0 woo
4 3 ppp
5 4 ttt
我期待下面的查询 return 3 4 5。我基本上想根据我在递归查询中传递的类别 ID,获取其下方的类别 ID 层次结构列表。感谢您的协助。
GO
WITH RecursiveQuery (CategoryID)
AS
(
-- Anchor member definition
SELECT a.CategoryID
FROM [SomeDB].[dbo].[SomeTable] AS a
WHERE a.ParentID = CategoryID
UNION ALL
-- Recursive member definition
SELECT b.CategoryID
FROM [SomeDB].[dbo].[SomeTable] AS b
INNER JOIN RecursiveQuery AS d
ON d.CategoryID = b.ParentID
)
-- Statement that executes the CTE
SELECT o.CategoryID
FROM [SomeDB].[dbo].[SomeTable] AS o
INNER JOIN RecursiveQuery AS d
ON d.CategoryID = 3
GO
如果你想要来自特定根的树:
DECLARE @rootCatID int = 3
;WITH LessonsTree (CatID)
AS
(
SELECT a.CategoryID
FROM [EducationDatabase].[dbo].[LessonCategory] AS a
WHERE a.CategoryID = @rootCatID ---<<<
UNION ALL
SELECT b.CategoryID
FROM LessonsTree as t
INNER JOIN [EducationDatabase].[dbo].[LessonCategory] AS b
ON b.ParentID = t.CatID
)
SELECT o.*
FROM LessonsTree t
INNER JOIN [EducationDatabase].[dbo].[LessonCategory] AS o
ON o.CategoryID = t.CatID
如评论中所述,锚点不受限制。最简单的解决方案是在锚点中添加标准
with RecursiveQuery (theID)
AS
(
SELECT a.ParentID --root id=parentid to include it and to prevent an extra trip to LessonCategory afterwards
FROM [LessonCategory] AS a
WHERE a.ParentID = 3 --restriction here
UNION ALL
SELECT b.CategoryID
FROM [LessonCategory] AS b
INNER JOIN RecursiveQuery AS d
ON d.theID = b.ParentID
)
SELECT* from RecursiveQuery
另一种选择是使递归查询具有通用性(无限制锚点)并保留 rootid。然后cte上的查询可以限制rootid(第一个选项可能更好,第二个主要适用于创建某种root-view的情况)
with RecursiveQuery
AS
(
SELECT a.ParentID theID, a.ParentID RootID
FROM [LessonCategory] AS a
UNION ALL
SELECT b.CategoryID, d.RootID
FROM [LessonCategory] AS b
INNER JOIN RecursiveQuery AS d
ON d.theID = b.ParentID
)
SELECT theID from RecursiveQuery where RootID = 3