MSSQL

时间:2017-01-25 05:46:53

标签: sql-server recursion

使用MSSQL,我试图遍历具有父子关系的表。我需要我的结果集,以便以正确的缩进方式获取所有元素,直到最后一个叶子,如下所示。

父母项目36有2个孩子17和18.每个孩子17和18分别有一个孩子26个,42个

 36 - 17 
 17 - 26 
 36 - 18 
 18 - 42 

但是我的递归在数据遍历方面工作正常,但顺序明智,它失败了。我的递归查询给出了以下输出

36 - 17 
36 - 18 
17 - 26 
18 - 42

它会立即显示所有级别,将它们存储在记录中,然后遍历这些级别的每个子级。

Oracle"先前连接"似乎工作正常,但是,MSSQL不是。我正在粘贴我正在使用的样本

WITH SRC (Level, PARITEMID, CHIITEMID) AS 
  (
    SELECT 
        0 as Level,
        PI.pitem_id as PARITEMID,
        CI.pitem_id as CHIITEMID
  FROM PI, CI JOIN <Condition> where PI.PITEM_ID =

  UNION ALL

  SELECT 
        Level + 1,
        PI1.pitem_id as PARITEMID,
        CI1.pitem_id AS CHIITEMID
       FROM PI1, CI1 JOIN <Condition>
)
Select * from SRC

我是否需要通过命令获得我在SRC上做的事情,或者递归本身是否存在根本问题?

1 个答案:

答案 0 :(得分:2)

您的字段名称不明确,所以我假设了以下内容:

cItem_ID - 子ID pItem_ID - 父ID item_Title - 项目名称/描述

另外,不清楚序列,所以我假设Item_Title(按字母顺序)。但是,您可以使用任何可用字段。 (参见“10000 + Row_Number()”行)

我应该注意,cteR1和cteR2不是必需的。我喜欢范围键,它们服务于许多目的。如果您确实将其删除,只需将最终订单设置为Order By A.Seq

即可
Declare @MyTable table (pItem_ID int,cItem_ID int,item_Title varchar(50))
Insert into @MyTable values 
 (null,36,'Item 36')
,(36,17,'Item 17')
,(17,26,'Item 26')
,(36,18,'Item 18')
,(18,42,'Item 42')


Declare @Top    int         = null      --<<  Sets top of Hier Try 7 
Declare @Nest   varchar(25) = '|-----'  --<<  Optional: Added for readability

;with cteP as (
      Select Seq  = cast(10000+Row_Number() over (Order by item_Title) as varchar(500))
            ,cItem_ID
            ,pItem_ID
            ,Lvl=1
            ,item_Title 
      From   @MyTable 
      Where  IsNull(@Top,-1) = case when @Top is null then isnull(pItem_ID,-1) else cItem_ID end
      Union  All
      Select Seq  = cast(concat(p.Seq,'.',10000+Row_Number() over (Order by r.item_Title)) as varchar(500))
            ,r.cItem_ID
            ,r.pItem_ID
            ,p.Lvl+1
            ,r.item_Title 
      From   @MyTable r
      Join   cteP p on r.pItem_ID = p.cItem_ID)
     ,cteR1 as (Select *,R1=Row_Number() over (Order By Seq) From cteP)
     ,cteR2 as (Select A.Seq,A.cItem_ID,R2=Max(B.R1) From cteR1 A Join cteR1 B on (B.Seq like A.Seq+'%') Group By A.Seq,A.cItem_ID )
Select A.R1  
      ,B.R2
      ,A.cItem_ID
      ,A.pItem_ID
      ,A.Lvl
      ,item_Title = Replicate(@Nest,A.Lvl-1) + A.item_Title
 From cteR1 A
 Join cteR2 B on A.cItem_ID=B.cItem_ID
 Order By A.R1

<强>返回

enter image description here