【问题标题】:inner join root of tree to table树的内部连接根到表
【发布时间】:2019-05-15 12:54:39
【问题描述】:

所以,我基本上有两张桌子。

|   id   | marketGroupID |
|--------|---------------|
|   1    |      134      |
|   2    |      868      |
|   3    |      387      |

第二张桌子:

| marketGroupid | parentGroupID |
|---------------|---------------|
|   134         |      5987     |
|   5987        |      NULL     |
|   868         |      8796     |
|   8796        |      387      |
|   387         |      NULL     |

最终结果应该是这样的:

|   id   | marketGroupID | parentGroupID |
|--------|---------------|---------------|
|   1    |      134      |     5987      |
|   2    |      868      |     387       |
|   3    |      387      |     387       |

现在我知道如何通过

INNER JOIN 两个表
SELECT table1.id,table1.marketGroupID,table2.parentGroupID FROM 'table1' INNER JOIN 'table2' ON table1.marketGroupID=table2.marketGroupID;

现在的问题是这只会显示直接父级。但我想要根父母。我不知道根父节点和子节点之间会有多少个节点。我所知道的是,一旦 parentGroupID 为 NULL,就会到达根父级。根父节点可能已经是 marketGroupID,就像 id=3 一样,或者中间可能有 3 个节点,就像 id=2 一样。

这里的重点是我不想要中间步骤。 “重复”中的第一个答案正是这样做的。此外,它是否假设了最大数量的中间步骤。每一步都有另一个左连接。我也不知道根父级最终会在哪个级别,因为我不知道我有多少中间步骤。所以我必须从左到右遍历每一行,直到遇到 null 和之前的最后一个值。

使用 cte 假设的答案,只有一张表。但我也有桌子。 而且我仍然只想要根父级,中间什么都没有。

从技术上讲,我什至不需要原始市场组 ID。对于表一中的每个 id,我只需要根 parentgroupid 就可以了。

【问题讨论】:

  • (显然,)这是一个常见问题解答。在考虑发布之前,请始终在谷歌上搜索您的错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有或没有您的特定字符串/名称,并阅读许多答案。如果您发布问题,请使用一个短语作为标题。请参阅How to Ask 和投票箭头鼠标悬停文本。

标签: database sqlite tree inner-join


【解决方案1】:

这是使用recursive CTE 的经典案例。

从一个为第一个表中的每个 id 生成一组行的表开始,该表遍历所有父链:

WITH RECURSIVE parents(id, child, parent) AS
  (SELECT id, NULL, marketGroupID FROM table1
  UNION ALL
   SELECT p.id, p.parent, t2.parentGroupID
   FROM table2 AS t2
   JOIN parents AS p ON p.parent = t2.marketGroupID)
SELECT * FROM parents;
id          child       parent
----------  ----------  ----------
1                       134
2                       868
3                       387
1           134         5987
2           868         8796
3           387
1           5987
2           8796        387
2           387

在这些结果中,子列为空的行是基组 ID,两列中都有值的行是指向根的链接链中的中间值,父列为空的行具有最终根table1 的每一行的 groupid。这是我们感兴趣的最后一组行。添加跟踪原始子组并过滤掉非根行给出最终结果:

WITH RECURSIVE parents(id, market, child, parent) AS
  (SELECT id, marketGroupID, NULL, marketGroupID FROM table1
  UNION ALL
   SELECT p.id, p.market, p.parent, t2.parentGroupID
   FROM table2 AS t2
   JOIN parents AS p ON p.parent = t2.marketGroupID)
SELECT id, market AS marketGroupID, child AS parentGroupID
FROM parents
WHERE parent IS NULL
ORDER BY id;
id          marketGroupId  parentGroupID
----------  -------------  -------------
1           134            5987
2           868            387
3           387            387

从技术上讲,我什至不需要原始市场组 ID。对于表一中的每个 id,我只需要根 parentgroupid 就可以了。

WITH RECURSIVE parents(id, child, parent) AS
  (SELECT id, NULL, marketGroupID FROM table1
  UNION ALL
   SELECT p.id, p.parent, t2.parentGroupID
   FROM table2 AS t2
   JOIN parents AS p ON p.parent = t2.marketGroupID)
SELECT id, child AS parentGroupID FROM parents WHERE parent IS NULL ORDER BY ID;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-04
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    相关资源
    最近更新 更多