我有一个输入表,如下所示:
ID NAME PARENT_ID
------------------------------------
1 ABC 0
2 DEF 1
3 XYZ 1
4 PQR 2
5 GHI 0
6 JKL 5
7 MNO 6
8 STU 6
我希望输出结果如下所示:字符串逗号分隔:
ABC, ABC -> DEF, ABC -> XYZ, ABC -> DEF -> PQR
GHI, GHI -> JKL, GHI -> JKL -> MNO, GHI -> JKL -> STU
我尝试过CTE和Cross Apply
,但没有成功。有人可以帮助我实现这个目标吗?
祝你好运
答案 0 :(得分:2)
检查输出的数据
create table tbl
(
ID int,
NAME varchar(20),
PARENT_ID int
)
insert into
tbl
values
(1 ,'ABC', 0),
(2, 'DEF', 1),
(3 ,'XYZ', 1),
(4 ,'PQR', 2)
select * from tbl
<强>查询强>
select table2.NAME as ChildName,table1.NAME as ParentName from tbl as table1
inner join tbl table2 on table1.ID = table2.PARENT_ID
答案 1 :(得分:1)
如果要检索分层列表:
with cte_1(ID, PARENT_ID, LABEL)
as (
select ID, PARENT_ID, cast(NAME as varchar(512))
from a_table
where PARENT_ID = 0
union all
select a.ID, a.PARENT_ID, cast(b.LABEL + ' --> ' +a.NAME as varchar(512))
from a_table a
join cte_1 b on a.PARENT_ID = b.ID
)
select LABEL from cte_1
order by LABEL
这会给你:
'ABC'
'ABC --> DEF'
'ABC --> DEF --> PQR'
'ABC --> XYZ'
'GHI'
'GHI --> JKL'
'GHI --> JKL --> MNO'
'GHI --> JKL --> STU'
如果您还希望将列表标记为单个字符串,则可以使用更多CTE:
-- recursively build the hierarchical list
with cte_1(ID, PARENT_ID, LABEL)
as (
select ID, PARENT_ID, cast(NAME as varchar(512))
from a_table
where PARENT_ID = 0
union all
select a.ID, a.PARENT_ID, cast(b.LABEL + ' --> ' +a.NAME as varchar(512))
from a_table a
join cte_1 b on a.PARENT_ID = b.ID
),
-- order them
cte_2 (NR, LABEL)
as (
select row_number() over (order by LABEL) as NR,
LABEL
from cte_1
),
-- recursive concatenation
cte_3 (NR, LABEL) as (
select NR, cast(LABEL as varchar(1024))
from cte_2 where NR = 1
union all
select a.NR, cast(b.LABEL + ', ' + a.LABEL as varchar(1024))
from cte_2 a
join cte_3 b on a.NR = b.NR + 1
)
-- get the result
select top 1 LABEL
from cte_3
order by len(LABEL) desc
结果是:
'ABC, ABC --> DEF, ABC --> DEF --> PQR, ABC --> XYZ, GHI, GHI --> JKL, GHI --> JKL --> MNO, GHI --> JKL --> STU'
答案 2 :(得分:0)
基于@bwt回答
您可以执行以下操作
declare @table table(Id int identity(1,1),
Name varchar(10),
Parent_Id int)
insert into @table(Name,Parent_Id) values('ABC',0)
insert into @table(Name,Parent_Id) values('DEF',1)
insert into @table(Name,Parent_Id) values('XYZ',1)
insert into @table(Name,Parent_Id) values('PQR',2)
insert into @table(Name,Parent_Id) values('GHI',0)
insert into @table(Name,Parent_Id) values('JKL',5)
insert into @table(Name,Parent_Id) values('MNO',6)
insert into @table(Name,Parent_Id) values('STU',6);
with c(ID, PARENT_ID, LABEL)
as (
select ID, PARENT_ID, cast(NAME as varchar(512))
from @table
where PARENT_ID = 0
union all
select a.ID, a.PARENT_ID, cast(b.LABEL + ' --> ' +a.NAME as varchar(512))
from @table a
join c b on a.PARENT_ID = b.ID
)
- 使用东西
select replace(STUFF((Select ',' +LABEL
from c t1
FOR XML PATH('')),1,1,''),'>','>')
这是一个有效的DEMO