sql – 如何从父子层次结构表创建查询

如何编写查询以将具有父/子层次结构的表转换为具有不同列中的层次结构级别的表?

我在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

解决方法

如果您具有固定或有限数量的级别,则可能不需要DYNAMIC sql.可以使用一点XML来“解析”路径.

考虑以下:

例:

Declare @YourTable Table ([Parent] varchar(50),[Child] varchar(50))
Insert Into @YourTable Values 
 (null,'S-1'),('S-1','S-11'),'S-12'),'S-13'),'S-14'),'S-15'),('S-11','S-111'),'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]',Level3 = xDim.value('/x[3]',Level4 = xDim.value('/x[4]',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

返回

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 &#39;EastRiver&#39; 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...