我有一个Group表,在该表中,有一个ParentId列,表示Group表中的父组。目的是从这些组中构建动态菜单。我知道我可以循环并抓住最后一个子节点并构造一个结果集,但我很好奇是否有更多的SQL-y方法来实现这一点。
该表包含int,int和varchar的Id,ParentId和Title字段。
基本上,层次结构可以这种方式构建(People是基础组):
People -> Male -> Boy
-> Man
-> Female
我想抓住每个分支的最后一个孩子。所以,{Boy,Man,Female}在这种情况下。
正如我所提到的,获取该信息不是问题。我只是在寻找一种更好的方法来获取它而不必编写一堆联合和循环,我可以基本上改变基组并动态地向外遍历整个层次结构。我不是一个真正的Db家伙,所以我不知道是否有一个光滑的方式这样做或不。
答案 0 :(得分:4)
要获取多个层次结构之一的叶级别,可以使用Recursive Common Table Expressions(CTE)枚举层次结构,然后检查哪些成员不是另一个组的父级,以过滤到叶子:< / p>
Declare @RootID int = 1
;with cte as (
select
Id,
ParentId,
Title
From
Groups
Where
Id = @RootID
Union All
Select
g.Id,
g.ParentId,
g.Title
From
cte c
Inner Join
Groups g
On c.Id = g.ParentID
)
Select
*
From
cte g
Where
Not Exists (
Select
'x'
From
Groups g2
Where
g2.ParentID = g.Id
);
您也可以使用左连接而不是不存在
来执行此操作答案 1 :(得分:1)
由于您使用的是SQL Server 2012,因此您可以利用hierarchyid
;这是劳伦斯的架构之后的一个例子:
CREATE TABLE Groups
(
Id INT NOT NULL
PRIMARY KEY
, Title VARCHAR(20)
, HID HIERARCHYID
)
INSERT INTO Groups
VALUES ( 1, 'People', '/' ),
( 2, 'Male', '/1/' ),
( 3, 'Female', '/2/' ),
( 4, 'Boy', '/1/1/' ),
( 5, 'Man', '/1/2/' );
SELECT Id
, Title
FROM Groups
WHERE HID NOT IN ( SELECT HID.GetAncestor(1)
FROM Groups
WHERE HID.GetAncestor(1) IS NOT NULL )
http://sqlfiddle.com/#!6/00330/1/0
结果:
ID TITLE
3 Female
4 Boy
5 Man