mysql 多级父子节点关系

zbq4xfa0  于 2023-03-17  发布在  Mysql
关注(0)|答案(1)|浏览(129)

我有一个包含2列的原始表,parent_node_id(父级)和node_id(子级),我希望得到3列的最终输出:“root”、“internal”和“leaf”节点。我想使用group_concat()和group by来实现所提供图片中的预期输出。
这是所提供图片中树形图的原始表。
| 父节点标识|节点标识|
| - ------|- ------|
| 零|十个|
| 零|二十个|
| 十个|1个|
| 十个|第二章|
| 第二章|三个|
| 第二章|四个|
| 二十个|五个|
| 二十个|六个|
| 六个|七|
| 六个|八个|
| 八个|九|
question case
我需要得到一个如下所示的输出:
| 根|内部的|叶|
| - ------|- ------|- ------|
| 十个|第二章|一、三、四|
| 二十个|六、八|五、七、九|
我试着创建3个CTE来获得单独的根节点、内部节点和叶节点。但是,我无法创建一个子关系表来给出与父节点和根节点的关系。
下面是我的尝试:

select
    m.node_id as root,
    group_concat(distinct i.node_id order by i.node_id separator ',') as internal,
    group_concat(distinct l.node_id order by l.node_id separator ',') as leaf
from craig_test.test m
left join craig_test.test r on m.node_id = r.node_id and r.parent_node_id is null
left join craig_test.test i on m.node_id = i.node_id and i.node_id in (select parent_node_id from craig_test.test where parent_node_id is not null)
left join craig_test.test l on m.node_id = l.node_id and l.node_id not in (select parent_node_id from craig_test.test where parent_node_id is not null)
-- where m.parent_node_id is null
group by 1
r3i60tvu

r3i60tvu1#

有更有效的方法来完成此操作,但这将提供您所要求的结果:

// build list of all nodes with their parent and whether they have children
WITH RECURSIVE hierarchy (root_node_id, node_id, has_children) AS (
    SELECT
        t.node_id,
        t.node_id,
        EXISTS (SELECT 1 FROM test WHERE parent_node_id = t.node_id)
    FROM test t
    WHERE t.parent_node_id IS NULL

    UNION ALL

    SELECT
        h.root_node_id,
        t.node_id,
        EXISTS (SELECT 1 FROM test WHERE parent_node_id = t.node_id)
    FROM test t
    JOIN hierarchy h ON t.parent_node_id = h.node_id
)
SELECT
    root_node_id AS root,
    GROUP_CONCAT(IF(has_children AND root_node_id <> node_id, node_id, NULL)) AS internal,
    GROUP_CONCAT(IF(NOT has_children, node_id, NULL)) AS leaf
FROM hierarchy
GROUP BY root_node_id;

CTE构建:
| 根节点ID|节点标识|有_子项|
| - ------|- ------|- ------|
| 十个|十个|1个|
| 二十个|二十个|1个|
| 十个|1个|无|
| 十个|第二章|1个|
| 二十个|五个|无|
| 二十个|六个|1个|
| 十个|三个|无|
| 十个|四个|无|
| 二十个|七|无|
| 二十个|八个|1个|
| 二十个|九|无|
然后GROUP BY查询输出:
| 根|内部的|叶|
| - ------|- ------|- ------|
| 十个|第二章|一、三、四|
| 二十个|六、八|五、七、九|

相关问题