2016-12-05 140 views
0

我寫了一個CTE查詢,這是我得到遞歸查詢最終結果CTE

Item  Parent Level Group 
-------------------------------------- 
CRSM/002 NULL  0 CRSM/002 
7160/002 CRSM/002 1 CRSM/002 
7823/085 CRSM/002 1 CRSM/002 
7864/038 CRSM/002 1 CRSM/002 
A543/033 CRSM/002 1 CRSM/002 
7460/530 CRSM/002 1 CRSM/002 
7280/007 7160/002 2 CRSM/002 
7009/130 7160/002 2 CRSM/002 
7567/001 7160/002 2 CRSM/002 
7009/126 7160/002 2 CRSM/002 
7280/003 7160/002 2 CRSM/002 
7280/008 7160/002 2 CRSM/002 
7280/005 7160/002 2 CRSM/002 
7574/004 7160/002 2 CRSM/002 
7280/004 7160/002 2 CRSM/002 
7280/006 7160/002 2 CRSM/002 
7454/224 7280/006 3 CRSM/002 
7093/633 7280/006 3 CRSM/002 
7202/010 7280/006 3 CRSM/002 
7202/013 7280/004 3 CRSM/002 
7454/253 7280/004 3 CRSM/002 
7093/553 7280/005 3 CRSM/002 
8865/957 7280/005 3 CRSM/002 
7202/012 7280/005 3 CRSM/002 
7093/696 7280/008 3 CRSM/002 
7202/011 7280/008 3 CRSM/002 
7454/294 7280/008 3 CRSM/002 
7202/009 7280/003 3 CRSM/002 
7454/201 7280/003 3 CRSM/002 
7656/002 7009/126 3 CRSM/002 
A556/075 7009/126 3 CRSM/002 
7574/002 7009/126 3 CRSM/002 
A902/027 7009/126 3 CRSM/002 
7093/418 7280/007 3 CRSM/002 
7454/245 7280/007 3 CRSM/002 
7202/008 7280/007 3 CRSM/002 

它與層次結構,父子關係和根父級分組的所有級別返回正確的數據結果。

的數據來正確的,但欲被佈置在樹結構中的數據,這意味着目前安排是這樣的電平0的行,然後再全部用水平1行等的元件.. ..上

我想要的安排是,首先是0級,然後是第一級第一個孩子,如果那個孩子有孩子,那麼這些孩子將在第二級等等,因此它將成爲實際的樹結構。 我不知道我是否能夠正確解釋我的問題。 我試過訂購和其他組合,但無法取得成功。

有什麼辦法嗎?

+4

你能提供你試過的嗎? – Susang

+0

事實上,我嘗試了多種方式,比如訂購不同組合的列,將自己的結果表加入其中,計算孩子數量,然後嘗試使用它以及更多,但沒有提供甚至接近的結果,這就是爲什麼我沒有發佈所有內容我嘗試過:(但是相信我,我在發佈問題之前先嚐試了很多, –

+3

你要做什麼的一個例子也會有幫助, –

回答

3

請檢查下面的帖子Parent/Child hierarchy like tree view

正如你可以從SQL recursive CTE query代碼看,我用深度(順序層次)和列進行排序。排序列實際上提供了樹視圖。 爲了使可視化更加清晰我添加了3個空格字符,同時在分層結構下降

樣本數據

declare @pc table(ID int, PARENT_ID int, [NAME] varchar(80)); 

insert into @pc 
select 1,NULL,'Bill' union all 
select 2,1,'Jane' union all 
select 3,1,'Steve' union all 
select 4,2,'Ben' union all 
select 5,3,'Andrew' union all 
select 6,NULL,'Tom' union all 
select 7,8,'Dick' union all 
select 8,6,'Harry' union all 
select 9,3,'Stu' union all 
select 10,7,'Joe'; 


; with r as (
    -- anchor part 
     select ID, 
      PARENT_ID, 
      [NAME], 
      depth = 0 , 
      sort = convert(varchar(max), convert(char(10), ROW_NUMBER() over (order by ID))) 
     from @pc 
     where PARENT_ID is null 

     union all 

    -- recursive part 
     select 
     pc.ID, 
     pc.PARENT_ID, 
     pc.[NAME], 
     depth = r.depth + 1, 
     sort = r.sort + convert(char(10), ROW_NUMBER() over (order by pc.ID)) 
     from r 
     inner join @pc pc on r.ID=pc.PARENT_ID 
) 
select 
    space(depth*3) + name 
from r 
order by sort 

輸出如下

enter image description here

關於數據 的排序enter image description here

+0

正如我在上面對Nebi的評論中所述,將row_number()轉換爲char並不能提供正確的序列。有趣的,嘗試選擇Seq from(選擇Seq = cast(1 as char(10))Union All Select Seq = cast(2 as char(10))Union All Select Seq = cast(10 as char(10)))通過1 –

+0

認真地,花點時間看看Row_Number()超過10項時會發生什麼 –

+0

這意味着筆記下的行數爲10000000000。太多考慮 – Eralper

2

只需要添加一個序列在構建期間。

我在Order By中使用ITEM,但是如果有效的話,您可以使用Item Description或其他演示序列鍵。

請參閱DECLARE @Top和@Nest中的註釋。看看會發生什麼

Declare @Table table (Item varchar(25), Parent varchar(25)) 
Insert into @Table values ('CRSM/002',NULL),('7160/002','CRSM/002'),('7823/085','CRSM/002'),('7864/038','CRSM/002'),('A543/033','CRSM/002'),('7460/530','CRSM/002'),('7280/007','7160/002'),('7009/130','7160/002'),('7567/001','7160/002'),('7009/126','7160/002'),('7280/003','7160/002'),('7280/008','7160/002'),('7280/005','7160/002'),('7574/004','7160/002'),('7280/004','7160/002'),('7280/006','7160/002'),('7454/224','7280/006'),('7093/633','7280/006'),('7202/010','7280/006'),('7202/013','7280/004'),('7454/253','7280/004'),('7093/553','7280/005'),('8865/957','7280/005'),('7202/012','7280/005'),('7093/696','7280/008'),('7202/011','7280/008'),('7454/294','7280/008'),('7202/009','7280/003'),('7454/201','7280/003'),('7656/002','7009/126'),('A556/075','7009/126'),('7574/002','7009/126'),('A902/027','7009/126'),('7093/418','7280/007'),('7454/245','7280/007'),('7202/008','7280/007') 

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

;with cteHB as (
     Select Seq = cast(1000+Row_Number() over (Order by Item) as varchar(500)) 
      ,Item 
      ,Parent 
      ,Lvl=1 
     From @Table 
     Where IsNull(@Top,'') = case when @Top is null then isnull(Parent,'') else Item end 
     Union All 
     Select Seq = cast(concat(p.Seq,'.',1000+Row_Number() over (Order by r.Item)) as varchar(500)) 
      ,r.Item 
      ,r.Parent 
      ,p.Lvl+1 
     From @Table r 
     Join cteHB p on r.Parent = p.Item) 
    ,cteR1 as (Select Seq,Item,R1=Row_Number() over (Order By Seq) From cteHB) 
    ,cteR2 as (Select A.Seq,A.Item,R2=Max(B.R1) From cteR1 A Join cteR1 B on (B.Seq like A.Seq+'%') Group By A.Seq,A.Item) 
Select B.R1 
     ,C.R2 
     ,A.Item 
     ,A.Parent 
     ,A.Lvl 
     ,Title = Replicate(@Nest,A.Lvl-1) + A.Item 
From cteHB A 
Join cteR1 B on A.Item=B.Item 
Join cteR2 C on A.Item=C.Item 
Order By B.R1,A.Seq 

返回

enter image description here

編輯 - 我要補充

範圍鍵是可選的,只是刪除cteR1和cteR2如果沒有必要的。我使用這些非遞歸聚合的鍵。

編輯 - CHAR(10)的示範

使用CONVERT(CHAR(10),ROW_NUMBER()OVER(ORDER BY河Item)))

enter image description here

+0

爲什麼要將'1000'添加到'Row_Number'?如果Row_Number超過1000行,會發生什麼情況? 但是無論哪種方式不是像@Eralper那樣的方法嗎?使用Row_Number作爲排序標準? – Nebi

+0

@Nebi - 包括測序。你需要超過9,999個同伴才能成爲關注 –

+0

@Nebi只是爲了好玩,試試 選擇Seq from(選擇Seq = cast(1 as char(10))Union All Select Seq = cast(2 as char(10)) Union All Select Seq = cast(10作爲字符(10)))1 –