我有以下两个表
表人
Id Name
1 A
2 B
3 C
4 D
5 E
表关系层次结构
ParentId CHildId
2 1
3 2
4 3
这将形成树状结构
D
|
C
|
B
|
A
ParentId和ChildId是人员表的ID列的外键
我需要编写可以获取顶级父级(即每个人的根源)的SQL。
遵循CTE可以针对每个用户执行此操作。我将其转换为一个功能,并为Person的每一行运行了它。我在Person表中大约有3k行,大约需要10秒。任何人都可以建议一种可以减少花费的方法。问题是CTE运行3k次后运行的功能
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
我还更新了原始问题的答案,但请放心,这里也有一份副本:
;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 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
SQLFiddle演示
请注意,稍有不同是在CTE的递归部分中。现在,每次从锚点部分重写ChildID。此外,还添加了ROW_NUMBER()函数(和新的CTE),以在最后获得每个孩子的顶层信息。
编辑-版本2
找到第一个查询的性能问题后,这是一个改进的版本。从上到下,而不是其他方式-消除CTE中多余的行的创建,在大量递归时应该更快得多:
;WITH RCTE AS
(
SELECT ParentId, CHildId, 1 AS Lvl FROM RelationHierarchy r1
WHERE NOT EXISTS (SELECT * FROM RelationHierarchy r2 WHERE r2.CHildId = r1.ParentId)
UNION ALL
SELECT rc.ParentId, rh.CHildId, Lvl+1 AS Lvl
FROM dbo.RelationHierarchy rh
INNER JOIN RCTE rc ON rc.CHildId = rh.ParentId
)
SELECT pc.Id AS ChildID, pc.Name AS ChildName, r.ParentId, pp.Name AS ParentName
FROM dbo.Person pc
LEFT JOIN RCTE r ON pc.id = r.CHildId
LEFT JOIN dbo.Person pp ON pp.id = r.ParentId
SQLFiddle演示
问题内容: 给出下表 给定一个,我需要找到其顶级父级()。 每天执行50-100次此查询。当前有100-200行(将来可能会更多)。多达8个层次的深度。我在考虑三种选择: 使用递归方法 创建一个视图 添加另一列(最不满意) 哪个效率最高? 问题答案: SQL2008 +: 为了存储层次结构,SQL Server包含HIERARCHYID数据类型。可以将上述数据“转换为”以使用“值”: 转换后,我将
问题内容: 在这种情况下,需要将元素滚动到视口中。问题是我不知道哪个元素是可滚动的。例如,在“纵向”中,身体是可滚动的,在“横向”中,身体是其他的元素(还有更多情况会更改可滚动的元素) 现在的问题是,给定需要滚动到视口中的元素,找到其第一个可滚动父级的最佳方法是什么? 我在这里设置了一个演示。使用按钮,您可以在两种不同情况之间切换 主体可以滚动或 有什么建议么 ? 问题答案: 只需检查滚动条是否可
最有效的方法是只使用纯javascript查找特定父元素的子元素(带有类或ID)。没有jQuery或其他框架。 在这种情况下,我需要找到parent的child1或child2,假设DOM树中可以有多个child1或child2类元素。我只想要父母的元素
我想知道是否有一种简单的方法可以从特定的窗口获得所有的顶层,包括顶层内的顶层。在下面的代码中,我留下了一个我想做的例子: Tkinter中是否有实现这一点的内置功能?
问题内容: 我有一个具有以下字段的MySQL表: 其中父字段表示上层ID。例如,水果id是1,橙色是水果之一,因此父对象是1。 但是我想做一个有效的MySQL查询来获取所有记录,格式为parent-> children-> parent-> children格式。我怎样才能做到这一点? 查询的结果记录应类似于: 问题答案: 您需要mysql不支持的递归联接。您唯一可以做的就是确定最大深度(由于p-
我正在研究一种寻找阳极父级的方法。我从根部开始,然后沿着叶子往下走,只要它们不是空的,不是孩子的节点。 下面是我的代码,它有点乱,因为我试着测试它看看哪里出了问题。