我的问题是如何标记返回行中的标识符,该标识符将告诉我返回的row.id是否有更多子项
Sample Data
id parenId Name parentName
9 8 nine eight
8 7 eight seven
6 8 six eight
5 8 five eight
4 8 four eight
3 8 three eight
2 1 two one
1 1 one one
12 7 tweleve seven
11 12 eleven twelve
如果我在下面的查询中传递了parentId为7,则返回
8 7 eight
6 8 six
5 8 five
4 8 four
3 8 three
12 7 tweleve
11 12 eleven
但我想要的是id为更多的孩子被标记为例如8和12有更多的孩子
8 7 eight haschidlren
6 8 six
5 8 five
4 8 four
3 8 three
12 7 tweleve haschidlren
11 12 eleven
WITH name_tree
AS (SELECT Id,
Parentid,
Name,
ParentName
FROM TableWithHiearchy
WHERE Parentid = 7
-- this is the starting point you want in your recursion
UNION ALL
SELECT c.Id,
c.Parentid,
c.Name,
ParentName
FROM TableWithHiearchy c
JOIN name_tree p
ON p.Id = c.ParentId -- this is the recursion
AND c.Id <> c.Parentid
)
SELECT distinct Id, parenId, Name
FROM name_tree
答案 0 :(得分:0)
我只想在case when exists (id is parent) then true else false end
rextester链接:http://rextester.com/RAU96705
create table TableWithHiearchy (
id int
, parentid int
, name varchar(32)
, parentname varchar(32)
)
insert into TableWithHiearchy values
(9,8,'nine','eight')
,(8,7,'eight','seven')
,(6,8,'six','eight')
,(5,8,'five','eight')
,(4,8,'four','eight')
,(3,8,'three','eight')
,(2,1,'two','one')
,(1,1,'one','one')
,(12,7,'tweleve','seven')
,(11,12,'eleven','twelve');
with name_tree as (
select
Id
, Parentid
, Name
, ParentName
, [Path]=convert(varchar(64),
isnull(convert(varchar(10),ParentId) + '.','')
+ convert(varchar(10),Id)
)
from TableWithHiearchy
where ParentId = 7
-- this is the starting point you want in your recursion
union all
select
c.Id
, c.Parentid
, c.Name
, c.ParentName --=p.Name
, Path=convert(varchar(64),p.Path + '.' + convert(varchar(10),c.Id))
from TableWithHiearchy c
join name_tree p
on p.Id = c.ParentId -- this is the recursion
and c.Id <> c.Parentid
)
select distinct Id, parentId, Name, Path
, HasChildren= case
when exists (
select 1
from name_tree i
where i.parentid=o.id
)
then 'HasChildren'
else ''
end
from name_tree o
结果
+----+----------+---------+---------+-------------+
| Id | parentId | Name | Path | HasChildren |
+----+----------+---------+---------+-------------+
| 3 | 8 | three | 7.8.3 | |
| 4 | 8 | four | 7.8.4 | |
| 5 | 8 | five | 7.8.5 | |
| 6 | 8 | six | 7.8.6 | |
| 8 | 7 | eight | 7.8 | HasChildren |
| 9 | 8 | nine | 7.8.9 | |
| 11 | 12 | eleven | 7.12.11 | |
| 12 | 7 | tweleve | 7.12 | HasChildren |
+----+----------+---------+---------+-------------+
我添加了路径,所以我可以直接看到。
答案 1 :(得分:0)
这是另一种选择。
在cte0中,我们将您的表标准化(请记住将@YourTable替换为您的实际表名。
在cteP中,我们构建了您的层次结构。
当 @Top 设置为 NULL 时,您将获得整个层次结构,否则请指定所需的顶级ID。
可以轻松地将TVT或存储过程作为参数传递给@Top
Declare @YourTable table (id int,parentId int,Name varchar(25),parentName varchar(25))
Insert Into @YourTable values
(9, 8, 'nine' ,'eight'),
(8, 7, 'eight' ,'seven'),
(6, 8, 'six' ,'eight'),
(5, 8, 'five' ,'eight'),
(4, 8, 'four' ,'eight'),
(3, 8, 'three' ,'eight'),
(2, 1, 'two' ,'one'),
(1, 1, 'one' ,'one'),
(12, 7, 'tweleve','seven'),
(11, 12,'eleven' ,'twelve')
Declare @Top int = null --<< Sets top of Hier Try 8 or 12
Declare @Nest varchar(25) = '|-----' --<< Optional: Added for readability
;with cte0 as (
Select Distinct ID,ParentID,Name From @YourTable
Union All
Select Distinct ID=parentID,ParentID=NULL,Name=parentName From @YourTable where ParentID not in (Select Distinct ID From @YourTable) ),
cteP as (
Select Distinct
Seq = cast(10000+Row_Number() over (Order by ID) as varchar(500))
,ID
,parentId
,Name
,Lvl=1
From cte0
Where IsNull(@Top,-1) = case when @Top is null then isnull(parentId,-1) else ID end
Union All
Select Seq = cast(concat(p.Seq,'.',10000+Row_Number() over (Order by r.ID)) as varchar(500))
,r.ID
,r.parentId
,r.Name
,p.Lvl+1
From cte0 r
Join cteP p on r.parentId = p.ID and r.id<>r.parentId)
,cteR1 as (Select *,R1=Row_Number() over (Order By Seq) From cteP )
,cteR2 as (Select A.Seq,A.ID,R2=Max(B.R1) From cteR1 A Join cteR1 B on (B.Seq like A.Seq+'%') Group By A.Seq,A.ID )
Select A.R1
,B.R2
,A.ID
,A.parentId
,A.Lvl
,Title = Replicate(@Nest,A.Lvl-1) + A.Name
,HasChildren = case when A.R1<>B.R2 then 'haschildren' else '' end
From cteR1 A
Join cteR2 B on A.ID=B.ID
Order By A.R1
<强>返回强>
现在,如果您将 @Top 设置为 8 ,您将获得