获取树中任何节点的 mysql 中 parent/child 关系的完整树,所有 parents
Get full tree of parent/child relationships in mysql of any node in the tree with all parents
示例数据:
+----+-------+----------+
| org_id | Name | ParentID |
+----+-------+----------+
| 1 | Org1 | 2 |
| 2 | Org2 | NULL |
| 3 | Org3 | 5 |
| 5 | Org5 | 1 |
| 14 | Org14 | 1 |
+----+-------+----------+
如果我以 org_id 1 (Org1) 用户身份登录。我想检索该用户的完整树。
我有以下递归查询:
WITH RECURSIVE cte (org_id, name, parent_id) AS (
SELECT org_id, name, parent_id
FROM organization
WHERE org_id = 1
UNION ALL
SELECT t1.org_id, t1.name, t1.parent_id
FROM organization t1
INNER JOIN cte t2 ON t1.parent_id = t2.org_id
)
SELECT * FROM cte;
但是,此查询仅提供了当前 ID(本例中为 Org1)的 children。如何将所有 parents 也包含在结果集中,以便准确地重建整个树?
编辑:我使用的是 MariaDB 版本 10.4.10
编辑:
我尝试了下面答案中的查询,但出现语法错误:
您的 CTE 获得了 children。为什么不使用另一个去相反的方向并获得 parents:
MySQL:
(WITH RECURSIVE cte (id, name, parent_id) AS (
SELECT id, name, parent_id
FROM organization
WHERE id = 1
UNION
SELECT t1.id, t1.name, t1.parent_id
FROM organization t1
INNER JOIN cte t2 ON t1.parent_id = t2.id
)
SELECT * FROM cte)
UNION
(WITH RECURSIVE cte (id, name, parent_id) AS (
SELECT id, name, parent_id
FROM organization
WHERE id = 1
UNION
SELECT t1.id, t1.name, t1.parent_id
FROM organization t1
INNER JOIN cte t2 ON t2.parent_id = t1.id
)
SELECT * FROM cte)
以及在 MySQL 和 MariaDB 中都有效的版本:
MySQL/MariaDB:
WITH RECURSIVE cte (id, name, parent_id, dir) AS (
SELECT id, name, parent_id, cast(null as char(10)) as dir
FROM organization
WHERE id = 1
UNION
SELECT t1.id, t1.name, t1.parent_id, ifnull(t2.dir, 'down')
FROM organization t1
INNER JOIN cte t2 ON t1.parent_id = t2.id and ifnull(t2.dir, 'down')='down'
UNION
SELECT t1.id, t1.name, t1.parent_id, ifnull(t2.dir, 'up')
FROM organization t1
INNER JOIN cte t2 ON t2.parent_id = t1.id and ifnull(t2.dir, 'up')='up'
)
SELECT id, name, parent_id FROM cte;
示例数据:
+----+-------+----------+
| org_id | Name | ParentID |
+----+-------+----------+
| 1 | Org1 | 2 |
| 2 | Org2 | NULL |
| 3 | Org3 | 5 |
| 5 | Org5 | 1 |
| 14 | Org14 | 1 |
+----+-------+----------+
如果我以 org_id 1 (Org1) 用户身份登录。我想检索该用户的完整树。
我有以下递归查询:
WITH RECURSIVE cte (org_id, name, parent_id) AS (
SELECT org_id, name, parent_id
FROM organization
WHERE org_id = 1
UNION ALL
SELECT t1.org_id, t1.name, t1.parent_id
FROM organization t1
INNER JOIN cte t2 ON t1.parent_id = t2.org_id
)
SELECT * FROM cte;
但是,此查询仅提供了当前 ID(本例中为 Org1)的 children。如何将所有 parents 也包含在结果集中,以便准确地重建整个树?
编辑:我使用的是 MariaDB 版本 10.4.10
编辑:
我尝试了下面答案中的查询,但出现语法错误:
您的 CTE 获得了 children。为什么不使用另一个去相反的方向并获得 parents:
MySQL:
(WITH RECURSIVE cte (id, name, parent_id) AS (
SELECT id, name, parent_id
FROM organization
WHERE id = 1
UNION
SELECT t1.id, t1.name, t1.parent_id
FROM organization t1
INNER JOIN cte t2 ON t1.parent_id = t2.id
)
SELECT * FROM cte)
UNION
(WITH RECURSIVE cte (id, name, parent_id) AS (
SELECT id, name, parent_id
FROM organization
WHERE id = 1
UNION
SELECT t1.id, t1.name, t1.parent_id
FROM organization t1
INNER JOIN cte t2 ON t2.parent_id = t1.id
)
SELECT * FROM cte)
以及在 MySQL 和 MariaDB 中都有效的版本:
MySQL/MariaDB:
WITH RECURSIVE cte (id, name, parent_id, dir) AS (
SELECT id, name, parent_id, cast(null as char(10)) as dir
FROM organization
WHERE id = 1
UNION
SELECT t1.id, t1.name, t1.parent_id, ifnull(t2.dir, 'down')
FROM organization t1
INNER JOIN cte t2 ON t1.parent_id = t2.id and ifnull(t2.dir, 'down')='down'
UNION
SELECT t1.id, t1.name, t1.parent_id, ifnull(t2.dir, 'up')
FROM organization t1
INNER JOIN cte t2 ON t2.parent_id = t1.id and ifnull(t2.dir, 'up')='up'
)
SELECT id, name, parent_id FROM cte;