2017-08-13 107 views
0

如何編寫我的查詢以將包含父級/子級別的錶轉換爲具有分層列中的層次結構級別的表?如何從父級子級別表中創建查詢

我在SQL Server中有一張表(來自SAP,沒有做任何改變,我相信),它給了我包含我的利潤中心的組的結構。該表的結構是一個經典的父子層次結構,如下所示。

Parent | Child 
--------+-------- 
S-1  | S-11 
S-1  | S-12 
S-1  | S-13 
S-1  | S-14 
S-1  | S-15 
S-11 | S-111 
S-11 | S-112 
..  | .. 
S-152 | S-1521 
S-152 | S-1522 
S-1522 | S-15221 

我想寫一個查詢,給我一個表,其中我爲每個組可以找到1級,2級,3級等。組。 1級是最高級別(並且將始終存在),2級是下一級別。可以有無限的水平,但在這個時候8級是最高的使用。

Group | Level 1 | Level 2 | Level 3 | Level 4 | Level 5 
--------+-----------+-----------+-----------+-----------+--------- 
S-111 | S-1  | S-11  | S-111  |   | 
S-11211 | S-1  | S-11  | S-112  | S-1121 | S-11211 
S-1211 | S-1  | S-12  | S-121  | S-1211 | 
S-1212 | S-1  | S-12  | S-121  | S-1212 | 
S-122 | S-1  | S-12  | S-122  |   |  
S-123 | S-1  | S-12  | S-123  |   | 
S-1311 | S-1  | S-13  | S-131  | S-1311 | 
S-1312 | S-1  | S-13  | S-131  | S-1312 | 
S-1321 | S-1  | S-13  | S-132  | S-1321 | 
S-141 | S-1  | S-14  | S-141  |   | 
S-151 | S-1  | S-15  | S-151  |   | 
S-1521 | S-1  | S-15  | S-152  | S-1521 | 
S-15221 | S-1  | S-15  | S-152  | S-1522 | S-15221 

我用谷歌和這個頁面找到最終的解決方案,但還沒有找到它。但我設法得到這麼多:

WITH MyTest as 
( 
    SELECT 
     P.PRCTR_CHILD, P.PRCTR_PARENT, 
     CAST(P.PRCTR_CHILD AS VARCHAR(MAX)) AS Level 
    FROM 
     [IBM_PA_Integration].[dbo].[PRCTRHIER] AS P 
    WHERE 
     P.PRCTR_PARENT = 'S-1000' –- S-1000 is a division 

    UNION ALL 

    SELECT 
     P1.PRCTR_CHILD, P1.PRCTR_PARENT, 
     CAST(P1.PRCTR_CHILD AS VARCHAR(MAX)) + ', ' + M.Level 
    FROM 
     [IBM_PA_Integration].[dbo].[PRCTRHIER] AS P1 
    INNER JOIN 
     MyTest M ON M.PRCTR_CHILD = P1.PRCTR_PARENT 
) 
SELECT * 
FROM MyTest 
WHERE PRCTR_PARENT = 'FS2004' –- FS2004 is the level top level/level above S-1000 
+0

您需要使用遞歸CTE,然後動態的支點上的結果。 –

回答

0

如果您有固定或有限的級別數量,您可能不需要DYNAMIC SQL。 「解析」路徑可以用一點XML完成。

考慮以下幾點:

例子:

Declare @YourTable Table ([Parent] varchar(50),[Child] varchar(50)) 
Insert Into @YourTable Values 
(null ,'S-1') 
,('S-1','S-11') 
,('S-1','S-12') 
,('S-1','S-13') 
,('S-1','S-14') 
,('S-1','S-15') 
,('S-11','S-111') 
,('S-11','S-112') 

;with cteP as (
     Select Child 
      ,Parent 
      ,PathID = cast(Child as varchar(500)) 
     From @YourTable 
     Where Parent is Null 
     Union All 
     Select Child = r.Child 
      ,Parent = r.Parent 
      ,PathID = cast(p.PathID+','+cast(r.Child as varchar(25)) as varchar(500)) 
     From @YourTable r 
     Join cteP p on r.Parent = p.Child) 
Select [Group] = Child 
     ,B.* 
From cteP A 
Cross Apply (
       Select Level1 = xDim.value('/x[1]','varchar(max)') 
         ,Level2 = xDim.value('/x[2]','varchar(max)') 
         ,Level3 = xDim.value('/x[3]','varchar(max)') 
         ,Level4 = xDim.value('/x[4]','varchar(max)') 
         ,Level5 = xDim.value('/x[5]','varchar(max)') 
       From (Select Cast('<x>' + replace(PathID,',','</x><x>')+'</x>' as xml) as xDim) as X 
      ) B 
    Order By PathID 

返回

enter image description here

+0

謝謝。這個解決方案適用於我,並給了我希望的結構。 – DickTaid81

+0

@ DickTaid81快樂它幫助 –

相關問題