我有两张桌子如下
表 Person
Id Name
1 A
2 B
3 C
4 D
5 E
Run Code Online (Sandbox Code Playgroud)
表 RelationHierarchy
ParentId CHildId
2 1
3 2
4 3
Run Code Online (Sandbox Code Playgroud)
这将形成树状结构
D
|
C
|
B
|
A
Run Code Online (Sandbox Code Playgroud)
ParentId和ChildId是Person Table的Id列的外键
我需要编写可以获取顶级父级即根的SQL.任何人都可以建议任何可以帮助我实现这一目标的SQL
Nen*_*vic 24
您可以使用递归CTE来实现:
DECLARE @childID INT
SET @childID = 1 --chield to search
;WITH RCTE AS
(
SELECT *, 1 AS Lvl FROM RelationHierarchy
WHERE ChildID = @childID
UNION ALL
SELECT rh.*, Lvl+1 AS Lvl FROM dbo.RelationHierarchy rh
INNER JOIN RCTE rc ON rh.CHildId = rc.ParentId
)
SELECT TOP 1 id, Name
FROM RCTE r
inner JOIN dbo.Person p ON p.id = r.ParentId
ORDER BY lvl DESC
Run Code Online (Sandbox Code Playgroud)
编辑 - 为所有儿童提供最高级别父母的更新请求:
;WITH RCTE AS
(
SELECT ParentId, ChildId, 1 AS Lvl FROM RelationHierarchy
UNION ALL
SELECT rh.ParentId, rc.ChildId, Lvl+1 AS Lvl
FROM dbo.RelationHierarchy rh
INNER JOIN RCTE rc ON rh.ChildId = rc.ParentId
)
,CTE_RN AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY r.ChildID ORDER BY r.Lvl DESC) RN
FROM RCTE r
)
SELECT r.ChildId, pc.Name AS ChildName, r.ParentId, pp.Name AS ParentName
FROM CTE_RN r
INNER JOIN dbo.Person pp ON pp.id = r.ParentId
INNER JOIN dbo.Person pc ON pc.id = r.ChildId
WHERE RN =1
Run Code Online (Sandbox Code Playgroud)
EDIT2 - 让所有人在最后改变JOINS:
SELECT pc.Id AS ChildID, pc.Name AS ChildName, r.ParentId, pp.Name AS ParentName
FROM dbo.Person pc
LEFT JOIN CTE_RN r ON pc.id = r.CHildId AND RN =1
LEFT JOIN dbo.Person pp ON pp.id = r.ParentId
Run Code Online (Sandbox Code Playgroud)
小智 6
要查找所有顶级父级,请使用如下查询:
select p.Name
from Person p
where not exists
(select null
from RelationHierarchy r
where r.ChildId = p.Id)
Run Code Online (Sandbox Code Playgroud)
SQLFiddle在这里。
要查找特定子级的顶级父级,请使用:
with cte as
(select t.ParentId TopParent, t.ChildId
from RelationHierarchy t
left join RelationHierarchy p on p.ChildId = t.ParentId
where p.ChildId is null
union all
select t.TopParent TopParent, c.ChildId
from cte t
join RelationHierarchy c on t.ChildId = c.ParentId)
select p.name
from cte h
join Person p on h.TopParent = p.Id
where h.ChildId=3 /*or whichever child is required*/
Run Code Online (Sandbox Code Playgroud)
SQLFiddle在这里。
小智 6
我已经使用此模式将层次结构中的项目与项目的根节点相关联.基本上递归层次结构,维护根节点的值作为附加到每一行的附加列.希望这可以帮助.
with allRows as (
select ItemId, ItemName, ItemId [RootId],ItemName [RootName]
from parentChildTable
where ParentItemId is null
union all
select a1.ItemId,a1.ItemName,a2.[RootId],a2.[RootName]
from parentChildTable a1
join allRows a2 on a2.ItemId = a1.ParentItemId
)
select * from allRows
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
47609 次 |
| 最近记录: |