简单的 CTE 递归查询

Simple CTE recursive query

很抱歉打扰这么简单的问题,但我决定学习 CTE 递归查询,即使在确定了许多来源和线程的范围后,我也无法进行查询。所以恳请大家指出错误

这里是table的一部分 我要查询的是:

ID        ContainerInstanceID  ItemID      ContentContainerInstanceID
--------- -------------------- ----------- --------------------------
73        40                   NULL        41        
69        40                   23885       NULL
68        40                   29683       NULL
67        40                   29686       NULL
72        41                   27392       NULL
71        41                   29235       NULL
70        41                   29213       NULL

我组装了这个简单的 CTE 查询:

;WITH ContainerContent_CTE(InstanceID,ItemID,ContentContainerInstanceID) AS
 (
  -- ROOT set accordig to input parameter
  SELECT ContainerInstanceID,SCA.ItemID,SCA.ContentContainerInstanceID 
  FROM StockContainerAssignments as SCA 
  WHERE SCA.ContainerInstanceID = 40  -- input parameter

  UNION ALL

  -- recursive data
  SELECT ContainerInstanceID,SCA2.ItemID,SCA2.ContentContainerInstanceID 
  FROM ContainerContent_CTE AS CC
  JOIN StockContainerAssignments as SCA2 on CC.InstanceID = SCA2.ContentContainerInstanceID
  )
SELECT * FROM ContainerContent_CTE;

我想要做的是获取一个顶级容器,在这个例子中它有 ID = 40,这是我的输入参数。然后,我尝试通过链接 ContainerInstanceID 和 ContentContainerInstanceID 来连接其他级别。在我的示例中,它不是 null ar row ID = 73。这应该向我的结果集添加另外 3 行(因此它看起来应该类似于我上面提供的示例数据),但我仍然只得到顶级行:

InstanceID   ItemID  ContentContainerInstanceID
-----------  ----------- --------------------------
40           29686       NULL
40           29683       NULL
40           23885       NULL
40           NULL        41        

我很感激能帮助我偶然发现这个主题的提示。

正如预期的那样,一个愚蠢的小错误以某种方式出现了 - 在 ON 子句中,我将父项和子项与相反的 ID 对连接起来。由于我只学习 CTE,所以对我来说很难看到。这里是固定的(供参考):

;WITH ContainerContent_CTE(InstanceID,temID,ContentContainerInstanceID) AS
 (
  -- ROOT set accordig to input parameter
  SELECT ContainerInstanceID,SCA.ItemID,SCA.ContentContainerInstanceID 
  FROM StockContainerAssignments as SCA 
  WHERE SCA.ContainerInstanceID = 40  -- input parameter

  UNION ALL

  -- recursive data
  SELECT ContainerInstanceID,SCA2.ItemID,SCA2.ContentContainerInstanceID 
  FROM ContainerContent_CTE AS CC
  INNER JOIN StockContainerAssignments as SCA2 on CC.ContentContainerInstanceID = SCA2.ContainerInstanceID)
SELECT * FROM ContainerContent_CTE;

感谢您的建议。

这对我有用

declare @t table (id int, instance int, container int);
insert into @t values 
               (73, 40, 41)       
             , (69, 40, NULL)
             , (68, 40, NULL)
             , (67, 40, NULL)
             , (72, 41, NULL)
             , (71, 41, NULL)
             , (70, 41, NULL);
select * from @t;
with cte as 
( select t.id, t.instance, t.container
  from @t t
  where t.instance = 40 
  union all 
  select t.id, t.instance, t.container
  from cte 
  join @t t 
    on t.instance = cte.container
)
select * from cte;

你只是有一些小事不合时宜。这应该适合你。

with ContainerContent_CTE as
(
    select SCA.ContainerInstanceID
        ,SCA.ItemID
        ,SCA.ContentContainerInstanceID 
    FROM StockContainerAssignments as SCA 
    WHERE SCA.ContainerInstanceID = 40  -- input parameter

    UNION ALL 

    select SCA.ContainerInstanceID
        ,SCA.ItemID
        ,SCA.ContentContainerInstanceID 
    FROM StockContainerAssignments as SCA
    inner join ContainerContent_CTE cte on cte.ContentContainerInstanceID = SCA.ContainerInstanceID
)

select *
from ContainerContent_CTE