2017-08-13 20 views
0

親/子階層を持つテーブルを、階層レベルが別の列にあるテーブルに変換するクエリを作成するにはどうすればよいですか?親子階層テーブルからクエリを作成する方法

私は利益センタを含むグループの構造を与えるSQL Serverのテーブルを持っています。表の構造は、以下に示すような古典的な親子階層です。

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 

最終的な解決策を見つけるためにGoogleとこのページを使用しましたが、まだ見つかりませんでした。しかし、私はこれを遠くに得ることができました:

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

レベルが固定または制限されている場合、ダイナミックSQLは必要ありません。 "Parsing"パスは少しの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ハッピー・イズ・ヘルプ –

関連する問題