【Mysql实现递归树查询】

大家好! 在我们日常工作中,经常会遇到一些问题,它们的一些解决方案通常会用到递归这一强大的技术手段。递归不仅能帮助我们更高效的解决问题,还可以使代码更简介、更易于理解, 今天我来给大家分享如何在实际工作中使用mysql8+实现递归

💡Tip !!! 需要Mysql 8+上的版本支持

在大型组织中,理解员工建的层级关系至关重要。无论是管理、报告和策划,一个清晰的组织层级视图都是必不可少的。但是如何有效地从一个大型、复杂的员工数据库中提取到这样的层级信息呢?

递归执行分析

mysql8+递归查询的实现是基于 WITH RECURSIVE语句。它从一个初始的"基础情况"开始,然后不断的重复或"递归" 的一个连接操作,直到满足某个条件为止。
以下是递归查询的基本结构:
1. 基础情况: 这是递归的起点,也就是根节点,在我们场景中根节点是CEO或者它的上级为null。
2. 递归情况: 基于基础情况,查询将继续扩展,包括下一级的员工,然后类推。

WITH RECURSIVE hierarchy AS (
	-- 基础情况
	...
	UNION ALL 
	-- 递归情况
	...
)
select xxx from hierarchy

demo数据

模拟插入10w条数据, 层级最高6层

DROP TABLE IF EXISTS employees;

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    manager_id INT,
    FOREIGN KEY (manager_id) REFERENCES employees(id)
);
-- 新增根节点数据
INSERT INTO employees (name) VALUES ('CEO');
-- 创建执行过程
DELIMITER $$
CREATE PROCEDURE InsertLargeAmountOfData()
BEGIN
    DECLARE id INT DEFAULT 2;
    DECLARE parentId INT DEFAULT 1;
    DECLARE counter INT DEFAULT 0;

    -- 第2层
    WHILE counter < 10 DO
        INSERT INTO employees (name, manager_id) VALUES (CONCAT('L2-', id), 1);
        SET id = id + 1;
        SET counter = counter + 1;
    END WHILE;

    SET counter = 0;
    -- 第3层
    WHILE counter < 100 DO
        SET parentId = 1 + FLOOR(counter / 10) + 1;
        INSERT INTO employees (name, manager_id) VALUES (CONCAT('L3-', id), parentId);
        SET id = id + 1;
        SET counter = counter + 1;
    END WHILE;

    SET counter = 0;
    -- 第4层
    WHILE counter < 1000 DO
        SET parentId = 11 + FLOOR(counter / 100);
        INSERT INTO employees (name, manager_id) VALUES (CONCAT('L4-', id), parentId);
        SET id = id + 1;
        SET counter = counter + 1;
    END WHILE;

    SET counter = 0;
    -- 第5层
    WHILE counter < 10000 DO
        SET parentId = 111 + FLOOR(counter / 1000);
        INSERT INTO employees (name, manager_id) VALUES (CONCAT('L5-', id), parentId);
        SET id = id + 1;
        SET counter = counter + 1;
    END WHILE;

    SET counter = 0;
    -- 第6层
    WHILE counter < 88889 DO
        SET parentId = 1111 + FLOOR(counter / 10000);
        INSERT INTO employees (name, manager_id) VALUES (CONCAT('L6-', id), parentId);
        SET id = id + 1;
        SET counter = counter + 1;
    END WHILE;

END$$
DELIMITER ;
-- 执行执行过程
CALL InsertLargeAmountOfData();

查询demo数据

WITH RECURSIVE hierarchy AS (
	-- 基础情况
	select id,name,manager_id from employees where manager_id is null
	UNION ALL 
	-- 递归情况
	select e.* from employees as e  inner join hierarchy as h on e.manager_id = h.id
)
select id,name,manager_id from hierarchy

结果
在这里插入图片描述
在以上图例中,通过调整manager_id is null 可以配置要查询某条数据及该数据所有子数据的查询出来的内容。

💡Tip! 查询的结果将以列表形式展现。若业务代码中需要完整的树状结构,可以在每个节点中关联其上级节点。最后,通过取manager_id is null的记录下的子节点数据,即可得到完整的树状数据。

扩展

字段扩展

在业务中常常会需要查询某条记录并返回该字段在组织层次中的位置,你可以参考以下代码:

WITH RECURSIVE hierarchy AS (
    -- 基础情况:从CEO开始
    SELECT id, name, manager_id, CAST(name AS CHAR(255)) AS hierarchy_path
    FROM employees
    WHERE manager_id IS NULL 

    UNION ALL

    -- 递归情况:为每个下级员工添加上级
    SELECT e.id, e.name, e.manager_id, CONCAT(h.hierarchy_path, ' > ', e.name)
    FROM employees e
    JOIN hierarchy h ON e.manager_id = h.id
)
SELECT id, name, manager_id, hierarchy_path 
FROM hierarchy
-- 查询某条数据条件
WHERE name = 'L3-111'
ORDER BY id;

结果如下图:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL递归查询结构是指在MySQL数据库中,通过使用递归查询语句来查询形结构的数据。形结构是一种常见的数据结构,例如组织架构、分类目录等都可以表示为形结构。 在MySQL中,可以使用递归查询语句来查询形结构的数据。递归查询语句使用了WITH RECURSIVE关键字来定义递归查询,并通过递归调用自身来实现形结构的遍历。 下面是一个示例,假设有一个名为categories的表,其中包含了id、name和parent_id字段,用于表示分类目录的形结构: ``` CREATE TABLE categories ( id INT PRIMARY KEY, name VARCHAR(50), parent_id INT ); INSERT INTO categories (id, name, parent_id) VALUES (1, '电子产品', NULL), (2, '手机', 1), (3, '电脑', 1), (4, '苹果手机', 2), (5, '小米手机', 2), (6, '华为手机', 2), (7, '苹果电脑', 3), (8, '联想电脑', 3); ``` 要查询整个分类目录的形结构,可以使用以下递归查询语句: ``` WITH RECURSIVE category_tree AS ( SELECT id, name, parent_id, 0 AS level FROM categories WHERE parent_id IS NULL UNION ALL SELECT c.id, c.name, c.parent_id, ct.level + 1 FROM categories c INNER JOIN category_tree ct ON c.parent_id = ct.id ) SELECT * FROM category_tree; ``` 这个查询语句中,首先定义了一个递归查询表category_tree,初始查询是根节点(parent_id为NULL的节点),然后通过UNION ALL和JOIN操作递归查询子节点,直到查询完整个形结构。 通过执行以上查询语句,可以得到如下结果: ``` id | name | parent_id | level --+--+--+------ 1 | 电子产品 | NULL | 0 2 | 手机 | 1 | 1 3 | 电脑 | 1 | 1 4 | 苹果手机 | 2 | 2 5 | 小米手机 | 2 | 2 6 | 华为手机 | 2 | 2 7 | 苹果电脑 | 3 | 2 8 | 联想电脑 | 3 | 2 ``` 这样就可以通过递归查询语句来获取整个形结构的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值