2017-01-25 137 views
0

使用MSSQL,我試圖遍歷一個父子關係的表。我需要我的結果集,以便以正確的縮進方式獲取所有元素,直到最後一片葉子,如下所示。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我下令它獲得做的,或者是有根本上有毛病遞歸本身?

+0

像往常一樣,如果你需要設置你必須指定'的最終結果一定順序ORDER BY'。如果沒有ORDER BY子句,結果集中的行可能以任何順序返回。 –

+0

這是一個父母的孩子關係。沒有我可以預先指定的訂單。如果你提供了一些樣本數據(十幾行應該足夠了),最好以「CREATE TABLE」和「INSERT」語句的形式提供,並且你可以提供一個可行的ORDER,我可以通過它來獲得每個層次結構,直到葉子 – Srikanth

+1

預期的查詢結果,你很可能會得到很好的答案。如果您使用您使用的SQL Server版本添加標籤,它也可能有所幫助。 –

回答

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

+0

非常感謝,這是跟蹤訂單和排序的好方法。它的工作 – Srikanth

+0

@Srikanth快樂它幫助。 –