Sql 如何从父子层次结构表创建查询
如何编写查询以将具有父/子层次结构的表转换为具有独立列中的层次结构级别的表 我在SAP的SQL Server中有一个表,没有做任何更改,我相信这会为我提供包含利润中心的组的结构。该表的结构是一个经典的父子层次结构,如下所示Sql 如何从父子层次结构表创建查询,sql,sql-server,parent-child,Sql,Sql Server,Parent Child,如何编写查询以将具有父/子层次结构的表转换为具有独立列中的层次结构级别的表 我在SAP的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 |
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
如果级别数量固定或有限,则可能不需要动态SQL。解析路径可以用一点XML来完成 考虑以下几点: 例如: 返回
您需要使用递归cte,然后对结果进行动态透视。谢谢。这个解决方案很适合我,给了我所希望的结构。@DickTaid81helped@JohnCappelletti是否可以使级别列处于动态状态?因此,在您的示例中,级别4和级别5不会出现,因为所有值都为null?@jvels不使用此方法。。。SQL Server在设计上是声明性的。获取动态列的唯一方法是使用动态SQL。
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