mysql树形结构_MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...

本文介绍了如何在MySQL中通过自定义函数`getChildList`,根据给定节点获取其所有子节点(包括枝干节点和叶子节点)。详细展示了创建数据表、编写查询函数的步骤,并提供了不同节点查询的示例。
摘要由CSDN通过智能技术生成

背景说明

需求:MySQL树形结构, 根据指定的节点,获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)

枝干节点:如果一个节点下还有子节点,则为枝干节点。

叶子节点:如果一个节点下不再有子节点,则为叶子节点。

问题分析

1、可以使用类似Java这种面向对象的语言,对节点集合进行逻辑处理,获取所有子节点。

2、直接自定义MySQL函数 getChildList,通过一层while循环,实现对指定节点的所有子节点进行查询。

功能实现

1、创建数据表

1)表结构截图如下(此处简单建一张表t_tree,id主键自增,uuid表示本节点,parent_uuid表示父节点):

11070b319efa664e3f455449869a9a38.png

2)建表语句如下:

/*Navicat Premium Data Transfer

Source Server : localhost

Source Server Type : MySQL

Source Server Version : 50724

Source Host : localhost:3306

Source Schema : test_db

Target Server Type : MySQL

Target Server Version : 50724

File Encoding : 65001

Date: 07/05/2019 21:04:57*/

SETNAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0;--------------------------------Table structure for t_tree------------------------------

DROP TABLE IF EXISTS`t_tree`;CREATE TABLE`t_tree` (

`id`int(20) NOT NULLAUTO_INCREMENT,

`uuid`int(20) NULL DEFAULT NULL,

`parent_uuid`int(20) NULL DEFAULT NULL,PRIMARY KEY(`id`) USING BTREE

) ENGINE= InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT =Dynamic;--------------------------------Records of t_tree------------------------------

INSERT INTO `t_tree` VALUES (1, 1, 0);INSERT INTO `t_tree` VALUES (2, 2, 0);INSERT INTO `t_tree` VALUES (3, 3, 0);INSERT INTO `t_tree` VALUES (4, 11, 1);INSERT INTO `t_tree` VALUES (5, 12, 1);INSERT INTO `t_tree` VALUES (6, 21, 2);INSERT INTO `t_tree` VALUES (7, 22, 2);INSERT INTO `t_tree` VALUES (8, 211, 21);INSERT INTO `t_tree` VALUES (9, 221, 22);INSERT INTO `t_tree` VALUES (10, 222, 22);INSERT INTO `t_tree` VALUES (11, 223, 22);INSERT INTO `t_tree` VALUES (12, 2231, 223);INSERT INTO `t_tree` VALUES (13, 2232, 223);INSERT INTO `t_tree` VALUES (14, 0, );SET FOREIGN_KEY_CHECKS = 1;

3)表数据结构如下:

1531db8855518679ea9d6620405b94f9.png

4)树形结构如下图:

246ecdc9233e4a8b2f53589aeebd0b51.png

2、编写查询叶子节点函数 getChildList,如下:

CREATE DEFINER=`root`@`localhost` FUNCTION `getChildList`(`nodeId` int) RETURNS varchar(1000) CHARSET utf8BEGIN

DECLARE childList VARCHAR(1000); # 返回叶子节点结果集DECLARE tempChild VARCHAR(1000); # 临时存放子节点SET childList = '';SET tempChild = CAST(nodeId as CHAR); # 将int类型转换为StringWHILE tempChild is not nullDO # 循环,用于查询节点下所有的子节点SET childList = CONCAT(childList, ',', tempChild); # 存入到返回结果中SELECT GROUP_CONCAT(uuid) INTO tempChild FROM t_tree where FIND_IN_SET(parent_uuid, tempChild) > 0; # 查询节点下所有子节点END WHILE;RETURN SUBSTRING(childList, 2); # 将返回结果处理,截取掉结果集前面的逗号END

其中,用到了几个MySQL的系统函数,如:CAST,CONCAT,GROUP_CONCAT,FIND_IN_SET。

3、调用函数

select getChildList(1) as childList;

0)查询节点0 的所有子节点:从树形图可以看到,应该是 0,1,2,3,11,12,21,22,211,221,222,223,2231,2232

908b8d7a43adb1672cf3740bd87084fe.png

1)查询节点1 的所有子节点:从树形图可以看到,应该是 1,11,12

2b69076168539afcbcb9c9d6d157a444.png

2)查询节点2 的所有子节点:从树形图可以看到,应该是 2,21,22,211,221,222,223,2231,2232

ef614238dff07816810e72bc75b6d997.png

3)查询节点3 的所有子节点:从树形图可以看到,应该是 3

50e8c68a7d9ef16e015776084acf619a.png

问题总结

该问题核心点是循环遍历查找子节点,按照上面的表数据和截图,阅读SQL函数,很好理解。

希望能帮到需要帮助的同行,谢谢。

PS:

1)如果需要 根据指定的节点,获取其下属的所有叶子节点(只包含叶子节点)。

3)如果需要 根据指定节点,获取其所在全路径节点序列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值