gpt4 book ai didi

sql - 如何限制CTE递归深度但选择通用表?

转载 作者:行者123 更新时间:2023-12-02 22:13:30 26 4
gpt4 key购买 nike

目前,我们有一个存储过程,它通过执行以下操作从原始架构中的表返回数据:

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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com