MySQL如何查找树形结构中某个节点及其子节点

 更新时间:2024年06月17日 11:26:48   作者:编程经验分享  
这篇文章主要介绍了MySQL如何查找树形结构中某个节点及其子节点问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

问题

设计表结构存储树形结构数据时,一般使用 parentId 来记录当前节点的父id。

表结构如下所示(以MySQL为例)

create table test
(
    id           varchar(30) collate utf8mb4_general_ci default '' not null
        primary key,
    name         varchar(100) collate utf8mb4_general_ci           null,
    parentId     varchar(30) collate utf8mb4_general_ci            null comment '父分类id'
)
    comment 'test';

查询出全部数据后通过每个节点各自的 parentId 就能够构造出整棵树。

但是,有些时候只想找到某个节点下的所有子节点,如果还是要查全表后构造整棵树再去查找目标节点,就显得很繁琐

如何解决

方法1:使用 MySQL 变量 + 函数

查询目标节点以及所有子节点,返回所有节点id,用【,】拼接

select GROUP_CONCAT(id) from (SELECT @ids as id,
                                      (SELECT @ids := GROUP_CONCAT(id) FROM test
                                       WHERE FIND_IN_SET(parentId, CONVERT(@ids USING utf8mb4) COLLATE utf8mb4_0900_ai_ci)
                                      ) AS childrenId
                               FROM test, (SELECT @ids := '节点id') var
                                WHERE @ids IS NOT NULL) t

同理,使用该方法还可以用来查询目标节点以及所有父节点

SELECT GROUP_CONCAT(id)  FROM
    (SELECT @id AS id,
            (SELECT @id := parentId FROM test WHERE id = CONVERT(@id USING utf8mb4) COLLATE utf8mb4_0900_ai_ci) AS pid
     FROM test, ( SELECT @id := '节点id') var WHERE @id IS NOT NULL) t

方法2:维护一个 path 字段

方法1的查询语句其实不好理解,不便后期维护。

(经评论区提醒,如果id之间存在包含关系的话,就不适用了)如果id字段长度固定的话,可以给表新增一个path字段。

create table test
(
    id           varchar(30) collate utf8mb4_general_ci default '' not null
        primary key,
    name         varchar(100) collate utf8mb4_general_ci           null,
    parentId     varchar(30) collate utf8mb4_general_ci            null comment '父分类id',
    path         varchar(500)                                      null comment 'id路径,逗号隔开'
)
    comment 'test';

path字段维护当前节点的所有父节点id,用【,】拼接

比如C节点的父节点是B,B节点的父节点是A,A是根节点

那么

  • C节点的path字段就为:A节点id,B节点id,C节点id
  • B节点的path字段就为:A节点id,B节点id
  • A节点的path字段就为:A节点id

然后根据path字段模糊查询便可以找到目标节点以及子节点了

select id from test where path like ‘%节点id%'

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mysql 5.7.17 安装配置方法图文教程(ubuntu 16.04)

    mysql 5.7.17 安装配置方法图文教程(ubuntu 16.04)

    这篇文章主要为大家分享了ubuntu 16.04下mysql 5.7.17 安装配置方法图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01
  • mysql函数拼接查询concat函数的使用方法

    mysql函数拼接查询concat函数的使用方法

    下面小编就为大家带来一篇mysql函数拼接查询concat函数的使用方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • mySQL 延迟 查询主表

    mySQL 延迟 查询主表

    在主外键表存在关系的时候如果加上"lazy=true"的话,则表明延迟,即只查询主表中的内容,而不查询外键表中的内容。
    2009-09-09
  • mysql序号rownum行号实现方式

    mysql序号rownum行号实现方式

    这篇文章主要介绍了mysql序号rownum行号实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • 登录mysql报错Can‘t connect to MySQL server on ‘localhost:3306‘ (10061)解决方法

    登录mysql报错Can‘t connect to MySQL server&n

    这篇文章主要给大家介绍了登录mysql报错 Can‘t connect to MySQL server on ‘localhost:3306‘ (10061)解决方法,文中有详细的解决步骤,需要的朋友可以参考下
    2023-09-09
  • mysql之脏读、不可重复读、幻读的区别及说明

    mysql之脏读、不可重复读、幻读的区别及说明

    这篇文章主要介绍了mysql之脏读、不可重复读、幻读的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • 深入了解mysql索引

    深入了解mysql索引

    这篇文章主要介绍了mysql索引的相关资料,文中讲解非常细致,帮助大家更好的理解和学习mysql,感兴趣的朋友可以了解下
    2020-07-07
  • MySQL使用distinct去掉查询结果重复的问题

    MySQL使用distinct去掉查询结果重复的问题

    这篇文章主要介绍了MySQL使用distinct去掉查询结果重复的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 碰到MySQL无法启动1067错误问题解决方法

    碰到MySQL无法启动1067错误问题解决方法

    创建primay key过程中发生了断电,当电脑再次启动时候,发现mysql 服务无法启动,使用 net start 提示 1067错误;后来只能通过手工删除数据文件,日志文件,再启动服务,然后导入数据来完成
    2013-01-01
  • mysql免安装版的实际配置方法

    mysql免安装版的实际配置方法

    本文主要向大家讲述的是MySQL 免安装版的实际配置方法,以及对其的相关的下载网址也有详细介绍,望你会有所收获。
    2010-08-08

最新评论