递归加入最近的祖先/父母记录在同一个表中?
Posted
技术标签:
【中文标题】递归加入最近的祖先/父母记录在同一个表中?【英文标题】:Recursivly Join Closest Ancestor/Parent To Record In Same Table? 【发布时间】:2021-12-03 08:26:25 【问题描述】:根据这个问题的标题,我试图在具有特定属性(以最接近的父记录为准)的同一个表中递归地与另一条记录连接记录,但我不完全确定如何处理。
我检查了here 和here,但遗憾的是对于我所需的用例来说不够具体。
示例 SQLFiddle:
http://sqlfiddle.com/#!18/0c5fb/2
我想要达到的最终结果是这样的,其中每一行都知道其最接近的祖先,其中 NeededElement 为真:
ElementID | ElementName | NeededElement | ParentElementID | ClosestNeededElementID |
---|---|---|---|---|
1 | Root Element | true | (null) | (null) |
2 | Child Element A | true | 1 | 1 |
3 | Child Element B | false | 1 | 1 |
4 | Child Element AA | false | 2 | 2 |
5 | Child Element AB | false | 2 | 2 |
6 | Child Element BA | false | 3 | 1 |
7 | Child Element BB | false | 3 | 1 |
非常感谢!
【问题讨论】:
【参考方案1】:您可以尝试对共享查询进行以下修改。
WITH CTE AS
(
SELECT
ElementID,
ElementName,
NeededElement,
ParentElementID,
ParentElementID as NextParentElementID,
CAST(NULL AS INT) as ClosestNeededElementID
FROM TestElements
UNION ALL
SELECT
CTE.ElementID,
CTE.ElementName,
CTE.NeededElement,
CTE.ParentElementID,
TestElements.ParentElementID as NextParentElementID,
CASE
WHEN TestElements.NeededElement=1 THEN TestElements.ElementID
END AS ClosestNeededElementID
FROM CTE
INNER JOIN TestElements ON CTE.NextParentElementID = TestElements.ElementID
WHERE CTE.ClosestNeededElementID IS NULL
)
SELECT
ElementID,
ElementName,
NeededElement,
ParentElementID,
ClosestNeededElementID
FROM CTE
WHERE (ParentElementId IS NULL) OR (ClosestNeededElementId IS NOT NULL)
ORDER BY ElementID ASC
View working demo fiddle
让我知道这是否适合你。
【讨论】:
太棒了,谢谢! :) 看来我需要复习一下我的 SQL 公用表表达式了!【参考方案2】:您可以使用条件为最近的父级保留一个运行列:
with cte(id, name, n_elem, p, l) as (
select *, null from testelements where parentelementid is null
union all
select t.*, case when c.n_elem = 1 then c.id else c.l end
from cte c join testelements t on t.parentelementid = c.id
)
select * from cte;
【讨论】:
以上是关于递归加入最近的祖先/父母记录在同一个表中?的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode二叉树#16二叉树的最近公共祖先(递归后序遍历,巩固回溯机制)
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先(二叉搜索树性质迭代递归)