2017-08-13 64 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快乐它帮助 –

相关问题