递归加入最近的祖先/父母记录在同一个表中?

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. 二叉搜索树的最近公共祖先(二叉搜索树性质迭代递归)

剑指 Offer 68 - I. 二叉搜索树的最近公共祖先(二叉搜索树性质迭代递归)

剑指 Offer 68 - I. 二叉搜索树的最近公共祖先(二叉搜索树性质迭代递归)