我在2列中有我的ChildID和ParentID,但是我想将这些列拆分为几列,但所有列仍指向其父级,并且在适用时也指向该父级的父级。
可能是数据集只有3个级别,如下所示,但在某些情况下可能也有4个级别,因此变得更加困难,因为它必须具有一定的动态性。
下面是我当前的数据集,一个子/父表:
ID, PARID,
1,
1,
10, 1
11, 1
20, 2
21, 2
100, 10
101, 10
110, 11
111, 11
200, 20
201, 20
210, 21
211, 21
以下是我想要的样子:
LVL1 LVL2 LVL3
1,
1,
1, 10,
1, 11,
2, 20,
2, 21,
1, 10, 100,
1, 10, 101,
1, 11, 110,
1, 11, 111,
2, 20, 200,
2, 20, 201,
2, 21, 210,
2, 21, 211,
ID名称不一定是我希望如何调用它们,但这仅是示例。另外,“孩子”并不总是包含父母的ID。
我无法在线找到正确的信息,最终只能找到如何创建子表/父表的方法,而不是尝试相反的方法。
非常感谢您的帮助。
编辑: 由于到目前为止的反应,我显示了我的实际数据,尽管实际上它有12000行,并且如您所见,它具有自动生成的唯一键,这可能是必须知道的:
OBJECTID,GROUNDID,MAINGROUNDID,
1, 024,
2, 025,
3, 026,
4, 02610, 026,
5, 02620, 026,
6, 02630, 026,
7, 02640, 026,
8, 02650, 026,
9, 027,
10, 028,
11, 029,
12, 030,
13, 03010, 030,
14, 03020, 030,
15, 03030, 030,
16, 03040, 030,
17, 030401, 03040,
编辑,到目前为止,结果是双行:
GROUNDID,Lvl1,Lvl2,Lvl3,Lvl4
006 006 NULL NULL NULL
007 007 NULL NULL NULL
008 008 NULL NULL NULL
009 009 NULL NULL NULL
010 010 NULL NULL NULL
011 011 NULL NULL NULL
014 014 NULL NULL NULL
015 015 NULL NULL NULL
016 016 NULL NULL NULL
017 017 NULL NULL NULL
018 018 NULL NULL NULL
019 019 NULL NULL NULL
020 020 NULL NULL NULL
021 021 NULL NULL NULL
022 022 NULL NULL NULL
023 023 NULL NULL NULL
024 024 NULL NULL NULL
025 025 NULL NULL NULL
026 026 NULL NULL NULL
02610 026 02610 NULL NULL
02620 026 02620 NULL NULL
02630 026 02630 NULL NULL
02640 026 02640 NULL NULL
02650 026 02650 NULL NULL
02610 02610 NULL NULL NULL
02620 02620 NULL NULL NULL
02630 02630 NULL NULL NULL
02640 02640 NULL NULL NULL
02650 02650 NULL NULL NULL
亲切的问候, 伊戈尔(Igor)
答案 0 :(得分:1)
这里是使用标准递归CTE来构建层次结构并使用一些XML来解析列的选项
示例
;with cteP as (
Select ID
,PARID
,PathID = cast(ID as varchar(max))
From YourTable
Where PARID is Null
Union All
Select ID = r.ID
,PARID = r.PARID
,PathID = p.PathID+concat(',',r.ID)
From YourTable r
Join cteP p on r.PARID = p.ID)
Select A.ID
,B.*
From cteP A
Cross Apply (
Select Lvl1 = xDim.value('/x[1]','int')
,Lvl2 = xDim.value('/x[2]','int')
,Lvl3 = xDim.value('/x[3]','int')
,Lvl4 = xDim.value('/x[4]','int')
From ( values (cast('<x>' + replace(PathID,',','</x><x>')+'</x>' as xml))) B(xDim)
) B
Order By PathID
返回
编辑-更新了真实数据
;with cteP as (
Select GROUNDID
,MAINGROUNDID
,PathID = cast(GROUNDID as varchar(max))
From YourTable
Where MAINGROUNDID is Null
Union All
Select GROUNDID = r.GROUNDID
,MAINGROUNDID = r.MAINGROUNDID
,PathID = p.PathID+concat(',',r.GROUNDID)
From YourTable r
Join cteP p on r.MAINGROUNDID = p.GROUNDID)
Select A.GROUNDID
,B.*
From cteP A
Cross Apply (
Select Lvl1 = xDim.value('/x[1]','varchar(50)')
,Lvl2 = xDim.value('/x[2]','varchar(50)')
,Lvl3 = xDim.value('/x[3]','varchar(50)')
,Lvl4 = xDim.value('/x[4]','varchar(50)')
From ( values (cast('<x>' + replace(PathID,',','</x><x>')+'</x>' as xml))) B(xDim)
) B
Order By PathID
返回
编辑2
我假设您的源数据看起来像这样
答案 1 :(得分:0)
对我来说,您的设计是错误的。您有一个Person
实体,该实体与其自身具有多对多关系:
-一个人可以有几个父母
-一个人可以是0个或多个孩子的父母。
在关系模型中,关系表表示多对多关系。因此,您应该有2个表:
这将允许您表示任何深度的父子关系。