目前,我们有一个存储过程,它通过执行以下操作从原始架构中的表返回数据:
WITH CTE AS
(
-- Start CTE off by selecting the id that was provided to stored procedure.
SELECT *
FROM [dbo].[TestTable]
WHERE [Id] = 1
-- Recursively add tasks that are children of records already found in previous iterations.
UNION ALL
SELECT t.*
FROM [dbo].[TestTable] as t
INNER JOIN CTE as tcte
ON t.[ParentId] = tcte.[Id]
)
SELECT *
FROM CTE
这很好,因为无论表架构如何变化,只要有 [Id] 和 [ParentId] 列,我就不必更新这个存储过程。我想做类似的事情,但也能够动态指定递归的深度。我见过的唯一方法是添加级别/深度标识符,如下所示:
WITH CTE AS
(
-- Start CTE off by selecting the task that was provided to stored procedure.
SELECT *, 0 as [Level]
FROM [dbo].[TestTable]
WHERE [Id] = 1
-- Recursively add tasks that are children of parent tasks that have already been found in previous iterations.
UNION ALL
SELECT t.*, [Level] + 1
FROM [dbo].[TestTable] as t
INNER JOIN CTE as tcte
ON t.[ParentId] = tcte.[Id]
WHERE [Level] < 2
)
SELECT *
FROM CTE
这效果很好,但带走了上一个查询的主要优点,因为最后选择 *
也会给我级别。是否有其他方法可以指定级别,但通常也可以从表中选择所有列?提前致谢。
最佳答案
如果您只想限制递归次数,则您应该能够使用 MAXRECURSION
query hint ,像这样:
WITH Department_CTE AS
(
SELECT
DepartmentGroupKey,
ParentDepartmentGroupKey,
DepartmentGroupName
FROM dimDepartmentGroup
WHERE DepartmentGroupKey = 2
UNION ALL
SELECT
Child.DepartmentGroupKey,
Child.ParentDepartmentGroupKey,
Child.DepartmentGroupName
FROM Department_CTE AS Parent
JOIN DimDepartmentGroup AS Child
ON Parent.ParentDepartmentGroupKey = Child.DepartmentGroupKey
)
SELECT * FROM Department_CTE
OPTION (MAXRECURSION 2)
编辑:
在回答评论中的问题时,不,当递归次数超过 MAXRECURSION 设置允许的次数时,您无法抑制出现的错误。如果我理解正确的话,你可以这样做:
WITH CTE AS
(
-- Start CTE off by selecting the task that was provided to stored procedure.
SELECT Id, 0 as [Level]
FROM [dbo].[TestTable]
WHERE [Id] = 1
-- Recursively add tasks that are children of parent tasks that have already been found in previous iterations.
UNION ALL
SELECT t.Id, [Level] + 1
FROM [dbo].[TestTable] as t
INNER JOIN CTE as tcte
ON t.[ParentId] = tcte.[Id]
WHERE [Level] < 2
),
CTE2 AS
(
SELECT TestTable.*
FROM CTE
INNER JOIN TestTable ON CTE.Id = TestTable.Id
)
SELECT * FROM CTE2;
假设您不打算更改层次结构或主键字段,这应该与上面的内容一样通用。
关于sql - 如何限制CTE递归深度但选择通用表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8885170/