【问题标题】:Recursive CTE result is infinite递归 CTE 结果是无限的
【发布时间】:2014-10-18 06:09:11
【问题描述】:

我在 SQL 中有一个表“ActionItem”,其中包含 ActionItemId、ItemName 和 ParentActionItemId 字段。我正在创建一个存储过程,它将接受 ActionItemId (Id) 并递归显示作为 Id 子项的所有 ActionItem 记录。为此,我使用了 CTE。

ALTER PROCEDURE [dbo].[SSP_ActionItem] 
@ActionItemId int
AS
BEGIN   
WITH ActionItemList AS
(
    --  Anchor
    SELECT ActionItem.ActionItemId,
           ActionItem.ItemName,
           ActionItem.ParentActionItemId 
    FROM ActionItem 
    WHERE ActionItemId=@ActionItemId

    UNION ALL

    --  Recursive query
    SELECT AIL.ActionItemId,
           AIL.ItemName,
           AIL.ParentActionItemId  
    FROM   ActionItem AS AI INNER JOIN  ActionItemList AS AIL 
    ON AI.ParentActionItemId=AIL.ActionItemId

)
SELECT * FROM ActionItemList
--option (maxrecursion 0)
END 

表结构:

   SELECT TOP 1000 [ActionItemId]
    ,[ParentActionItemId]
    ,[ItemName]
    FROM [ActionItem]

这个 sp 返回无限记录。我不明白我哪里出错了。谁能帮忙?我是这个 CTE 概念的新手。

【问题讨论】:

  • 返回无限记录需要多长时间?
  • 如果您可以共享表结构和示例数据可能会有所帮助
  • 您的递归部分没有ActionItem 表中的任何列,并且基本上重复了来自锚点的所有信息。它将在设计上是无限的。 @JasonGoemaat:喜欢你的问题:)
  • "ON AI.ParentActionItemId=AIL.ActionItemId" 这是递归部分,它有来自 ActionItem 的 ParentActionItemId 列
  • 看看递归部分的SELECT列表

标签: sql sql-server recursion common-table-expression


【解决方案1】:

程序应该是:

ALTER PROCEDURE [dbo].[SSP_ActionItem] 
@ActionItemId int
AS
BEGIN   
WITH ActionItemList AS
(
    --  Anchor
    SELECT ActionItem.ActionItemId,
           ActionItem.ItemName,
           ActionItem.ParentActionItemId 
    FROM ActionItem 
    WHERE ActionItemId=@ActionItemId

    UNION ALL

    --  Recursive query
    SELECT AI.ActionItemId,
           AI.ItemName,
           AI.ParentActionItemId  
    FROM   ActionItem AS AI INNER JOIN  ActionItemList AS AIL 
    ON AI.ParentActionItemId=AIL.ActionItemId

)

【讨论】:

  • 问题解决了......但我仍然想知道为什么我必须在 CTE 的递归查询部分中包含 ActionItem 列?因为我从逻辑上看待它的方式,如果我使用表或 CTE 结果几乎没有关系,因为它们都指向同一个列......这里不知道哪个概念?
  • 之前您将 CTE 结果的列包含在递归查询中,以无限循环结束。例如。看这个问题的数据stackoverflow.com/questions/14274942/…如果包含,CTE的结果会一次又一次地选择“Ken”,它不会选择“Terri”或“Roberto”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-08
  • 2020-06-17
  • 1970-01-01
  • 2017-08-31
  • 1970-01-01
  • 2016-08-15
  • 1970-01-01
相关资源
最近更新 更多