• MySQL 树形结构 根据指定节点 获取其所有父节点序列


    背景说明

    需求:MySQL树形结构, 根据指定的节点,获取其所有父节点序列。

    问题分析

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

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

    功能实现

    1、创建数据表

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

    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
    */
    
    SET NAMES 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 NULL AUTO_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)表数据结构如下:

    4)树形结构如下图:

    2、编写查询父节点函数 getParentNodeList,如下:

    CREATE DEFINER=`root`@`localhost` FUNCTION `getParentNodeList`(`nodeId` int) RETURNS varchar(1000) CHARSET utf8
    BEGIN
        DECLARE parentList VARCHAR(1000);      # 返回父节点结果集
        DECLARE tempParent VARCHAR(1000);      # 临时存放父节点
    
        SET parentList = '';
        SET tempParent = CAST(nodeId as CHAR); # 将int类型转换为String
    
        WHILE tempParent is not null DO        # 循环,用于查询节点上所有的父节点
            SET parentList = CONCAT(parentList, ',', tempParent);   # 存入到返回结果中
            SELECT parent_uuid INTO tempParent FROM t_tree where uuid = tempParent;   # 查询节点上所有父节点
        END WHILE;
        RETURN SUBSTRING(parentList, 2);       # 将返回结果处理,截取掉结果集前面的逗号
    END

    其中,用到了很多MySQL的系统函数,如:CAST,SUBSTRING,CONCAT。

     3、调用函数

    select getParentNodeList(2232) as parentNodeList;

    0)查询节点0 的父节点:从树形图可以看到,应该是 0

    1)查询节点21 的父节点:从树形图可以看到,应该是 21,2,0

    2)查询节点211 的父节点:从树形图可以看到,应该是 211,21,2,0

    3)查询节点2231 的父节点:从树形图可以看到,应该是 2231,223,22,2,0

    问题总结

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

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

     PS:

    1)如果需要 根据指定的节点,获取其下属的所有子节点(包含路径上的所有枝干节点和叶子节点)

    请参考本人的另一篇博文:https://www.cnblogs.com/miracle-luna/p/10828592.html

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

    请参考本人的另一篇博文:https://www.cnblogs.com/miracle-luna/p/10828476.html

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

    请参考本人的另一篇博文:https://www.cnblogs.com/miracle-luna/p/10878366.html

  • 相关阅读:
    Python Django 之 Template 模板语言简介
    Prometheus
    MySQL 存储过程中执行DDL
    Mysql 存储过程-转载
    Mysql 时间类型整理
    MySQL 5.7 分区表性能下降的案例分析
    Mysql 分区表-分区操作
    Mysql 中Left/Right join on后面and和where条件查询的差异-Mysql SQL运算符是有优先级
    MySQL出现Waiting for table metadata lock的原因以及解决方法
    Python 字符串转换为字典(String to Dict)
  • 原文地址:https://www.cnblogs.com/miracle-luna/p/10878224.html
Copyright © 2020-2023  润新知