在同一 table 中查找所有没有直接 id-parentid 的祖先

Find all ancestors without direct id-parentid in same table

我有一个跨越两个 table 的 parent-child 结构。第一个 table 有 BOM_ID 的帐单和 ITEM_ID 的相关 children 项目。另一个 parent 项目有 BOM_ID 和 ITEM_ID。

我可以通过以下查询找到 parents' ITEM_ID 的第一层

SELECT item_id
FROM bomversion
WHERE bom_id IN (SELECT bom_id FROM bom WHERE item_id = 1)

所以,为了找到所有的祖先,我将不得不重复这一步。我试图查看 CTE 和递归技术,但所有示例在相同的 table 中都有 parentid 和 childid。我想不通这个。

如果1是2的child,2是3的child,3是4的child,2也是5的child,我是查找以下结果:

ChildID ParentID
1 2
2 3
2 5
3 4

起点将是一个特定的 ChildID。


解决方案

根据 Adnan Sharif 的建议,我找到了解决问题的方法:

WITH items_CTE AS (
  -- create the mapping of items to consider
  SELECT
   B.ITEMID AS Child_id,
   BV.ITEMID AS Parent_Id
  FROM BOM AS B
  INNER JOIN BOMVERSION AS BV
  ON B.BOMID = BV.BOMID
), parent_child_cte AS (
  -- select those items as initial query
  SELECT
    Child_id,
    Parent_id
  FROM items_CTE
  WHERE Child_id = '111599' -- this is the starting point
  UNION ALL
  -- recursive approach to find all the ancestors
  SELECT
   c.Child_Id,
   c.Parent_Id
  FROM items_CTE c
  JOIN parent_child_cte pc
  ON pc.Parent_Id = c.Child_id
)
SELECT * FROM parent_child_cte

根据您在评论中分享的 dbfiddle,如果我理解正确的话,您想要显示 child 的所有 parents 的行。 例如,让我们考虑层次结构,1 是 2 的 child,2 是 3 的 child,3 是 4 的 child。您希望最终结果为,

child_id parent_id
1 2
1 3
1 4
2 3
2 4
3 4

如果是这样,我们可以使用递归 CTE 来构建 table。首先,我们需要基于 bom_id 在这两个 table 之间建立关系,然后我们需要找出 parent-child 关系。之后,我们将根据初始查询添加行。请看下面的代码。

WITH RECURSIVE items_CTE AS (
  -- create the mapping of items to consider
  SELECT
   B.Item_id AS Child_id,
   BV.Item_id AS Parent_Id
  FROM BOM AS B
  INNER JOIN BOMVERSION AS BV
  ON B.bom_id = BV.bom_id
), parent_child_cte AS (
  -- select those items as initial query
  SELECT
    Child_id,
    Parent_id
  FROM items_CTE
  
  UNION
  
  -- recursive approach to find all the ancestors
  SELECT
   parent_child_cte.Child_Id,
   items_CTE.Parent_Id
  FROM items_CTE
  INNER JOIN parent_child_cte
  ON parent_child_cte.Parent_Id = items_CTE.Child_id
)
SELECT * FROM parent_child_cte