database - 树的内部连接根到表
问题描述
所以,我基本上有两张桌子。
| 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 一样,或者在 id=2 之间可能有 3 个节点。
这里的重点是我不想要中间步骤。“重复”中的第一个答案正是这样做的。此外,它是否假设了最大数量的中间步骤。每一步都有另一个左连接。我也不知道根父级最终会在哪个级别,因为我不知道我有多少中间步骤。所以我必须从左到右遍历每一行,直到遇到 null 和之前的最后一个值。
使用 cte 假设的答案只有一张表。但我也有桌子。而且我仍然只想要根父级,中间什么都没有。
从技术上讲,我什至不需要原始市场组 ID。对于表一中的每个 id,我只需要根 parentgroupid 就可以了。
解决方案
这是使用递归 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,两列中都有值的行是指向根的链接链中的中间值,父列为空的行具有每个的最终根 groupid行table1
。这是我们感兴趣的最后一组行。添加跟踪原始子组并过滤掉非根行会给出最终结果:
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;
推荐阅读
- sql - MS SQL SERVER 在从池中获取连接之前经过的超时时间
- r - 转换 Python 列表并将其存储在 R 环境中。所以我可以使用 rpy2.objects.r() 访问列表
- elasticsearch - 具有过滤器匹配的 Elasticsearch 聚合
- video-streaming - 视频流在几秒钟后冻结,但声音正常
- sql - 包括存在数据的指标,但不包括在结果中
- amazon-web-services - Packer 可以在本地构建 AMI(即,不连接到 AWS)吗?
- python - 舍入包含数字和字符串的数据框中的所有数字?
- javascript - Nuxtjs toastr 和数据表插件在 adminLTE - 3 模板中不起作用
- c# - 如何使用 C# 将不同方法的结果加载到变量中
- apache-spark - 在 Kubernetes 上运行 Spark 时,是否可以作为另一个用户以 root 身份运行?