pho*_*nix 0 t-sql common-table-expression hierarchical-data
我有一个分层表,其中为每个孩子定义了一个父 id(除了父 id 为空的顶级孩子)。现在我想为选定的孩子在一行中显示每个父 ID。
我试图使用 CTE,但 CTE 正在向初始集添加额外的记录。相反,我想用父母列表更新初始集(SELECT 语句选择一些孩子)。
表示例(表 1):
ChildID ParentID
A P
P Q
Q Z
B P
C F
F M
M Q
D H
H Y
Y NULL
Z NULL
Run Code Online (Sandbox Code Playgroud)
如果初始语句将从子 ID 列表中选择 C、A、Q,则预期结果如下:
Selected Child Parent IDs
C F, M, Q, Z
A P, Q, Z
Q Z
Run Code Online (Sandbox Code Playgroud)
您使用 CTE 执行此操作是正确的,但是您必须将所有行放入一列中(请参阅交叉应用 - xml 路径)。
with cte (selected, child, parent) as
(
select s.id, t.*
from @t as t
inner join @selected as s on t.childid = s.id
union all
select cte.selected, t.*
from @t as t
inner join cte on t.childid = cte.parent
where cte.parent is not null
)
select distinct
t.selected as [Selected Child],
left(a.parents,len(a.parents) - 1) as Parents
from cte t
cross apply (select cast(parent + ',' as text)
from cte tt
where t.selected = tt.selected
for xml path('')) a(parents);
Run Code Online (Sandbox Code Playgroud)
使用样本数据:
declare @t as table
(
childid char(1),
parentid char(1)
);
declare @selected as table
(
id char(1)
);
insert into @t (childid,parentid) values ('a','p'),
('p','q'),
('q','z'),
('b','p'),
('c','f'),
('f','m'),
('m','q'),
('d','h'),
('h','y'),
('y',null),
('z',null);
insert into @selected (id) values ('c'),('a'),('q');
with cte (selected, child, parent) as
(
select s.id, t.*
from @t as t
inner join @selected as s on t.childid = s.id
union all
select cte.selected, t.*
from @t as t
inner join cte on t.childid = cte.parent
where cte.parent is not null
)
select distinct
t.selected as [Selected Child],
left(a.parents,len(a.parents) - 1) as Parents
from cte t
cross apply (select cast(parent + ',' as text)
from cte tt
where t.selected = tt.selected
for xml path('')) a(parents);
Run Code Online (Sandbox Code Playgroud)