翼度科技»论坛 编程开发 mysql 查看内容

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

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
问题

设计表结构存储树形结构数据时,一般使用 parentId 来记录当前节点的父id。
表结构如下所示(以MySQL为例)
  1. create table test
  2. (
  3.     id           varchar(30) collate utf8mb4_general_ci default '' not null
  4.         primary key,
  5.     name         varchar(100) collate utf8mb4_general_ci           null,
  6.     parentId     varchar(30) collate utf8mb4_general_ci            null comment '父分类id'
  7. )
  8.     comment 'test';
复制代码
查询出全部数据后通过每个节点各自的 parentId 就能够构造出整棵树。
但是,有些时候只想找到某个节点下的所有子节点,如果还是要查全表后构造整棵树再去查找目标节点,就显得很繁琐

如何解决


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

查询目标节点以及所有子节点,返回所有节点id,用【,】拼接
  1. select GROUP_CONCAT(id) from (SELECT @ids as id,
  2.                                       (SELECT @ids := GROUP_CONCAT(id) FROM test
  3.                                        WHERE FIND_IN_SET(parentId, CONVERT(@ids USING utf8mb4) COLLATE utf8mb4_0900_ai_ci)
  4.                                       ) AS childrenId
  5.                                FROM test, (SELECT @ids := '节点id') var
  6.                                 WHERE @ids IS NOT NULL) t
复制代码
同理,使用该方法还可以用来查询目标节点以及所有父节点
  1. SELECT GROUP_CONCAT(id)  FROM
  2.     (SELECT @id AS id,
  3.             (SELECT @id := parentId FROM test WHERE id = CONVERT(@id USING utf8mb4) COLLATE utf8mb4_0900_ai_ci) AS pid
  4.      FROM test, ( SELECT @id := '节点id') var WHERE @id IS NOT NULL) t
复制代码
方法2:维护一个 path 字段

方法1的查询语句其实不好理解,不便后期维护。
(经评论区提醒,如果id之间存在包含关系的话,就不适用了)如果id字段长度固定的话,可以给表新增一个path字段。
  1. create table test
  2. (
  3.     id           varchar(30) collate utf8mb4_general_ci default '' not null
  4.         primary key,
  5.     name         varchar(100) collate utf8mb4_general_ci           null,
  6.     parentId     varchar(30) collate utf8mb4_general_ci            null comment '父分类id',
  7.     path         varchar(500)                                      null comment 'id路径,逗号隔开'
  8. )
  9.     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字段模糊查询便可以找到目标节点以及子节点了
  1. select id from test where path like ‘%节点id%'
复制代码
总结

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

来源:https://www.jb51.net/database/3228060iv.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具