0


MySQL5.7 递归查询 看这一篇就够了 简单易懂

创建测试环境#

在线数据库 http://sqlfiddle.com/

1. 创建表
  1. DROP TABLE IF EXISTS `dept`;
  2. CREATE TABLE `dept` (
  3. `id` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  4. `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  5. `pid` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  6. PRIMARY KEY (`id`) USING BTREE
  7. ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
2. 插入测试数据#
  1. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1000', '总公司', NULL);
  2. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1001', '北京分公司', '1000');
  3. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1002', '上海分公司', '1000');
  4. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1003', '北京研发部', '1001');
  5. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1004', '北京财务部', '1001');
  6. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1005', '北京市场部', '1001');
  7. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1006', '北京研发一部', '1003');
  8. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1007', '北京研发二部', '1003');
  9. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1008', '北京研发一部一小组', '1006');
  10. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1009', '北京研发一部二小组', '1006');
  11. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1010', '北京研发二部一小组', '1007');
  12. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1011', '北京研发二部二小组', '1007');
  13. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1012', '北京市场一部', '1005');
  14. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1013', '上海研发部', '1002');
  15. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1014', '上海研发一部', '1013');
  16. INSERT INTO `dept`(`id`, `name`, `pid`) VALUES ('1015', '上海研发二部', '1013');
  17. commit;
3. 查看一下刚才插入的数据#
  1. select * from dept;

结果如下:

  1. id |name |pid |
  2. ----+---------+----+
  3. 1000|总公司 | |
  4. 1001|北京分公司 |1000|
  5. 1002|上海分公司 |1000|
  6. 1003|北京研发部 |1001|
  7. 1004|北京财务部 |1001|
  8. 1005|北京市场部 |1001|
  9. 1006|北京研发一部 |1003|
  10. 1007|北京研发二部 |1003|
  11. 1008|北京研发一部一小组|1006|
  12. 1009|北京研发一部二小组|1006|
  13. 1010|北京研发二部一小组|1007|
  14. 1011|北京研发二部二小组|1007|
  15. 1012|北京市场一部 |1005|
  16. 1013|上海研发部 |1002|
  17. 1014|上海研发一部 |1013|
  18. 1015|上海研发二部 |1013|

向上递归#

根据一个子节点id,查询所有父节点(包含⾃⾝)
  1. -- 根据一个子节点id,查询所有父节点(包含⾃⾝)
  2. SELECT t2.id, t2.name, t2.pid
  3. FROM (SELECT @r as _id,
  4. (SELECT @r := pid FROM dept WHERE id = _id) as pid,
  5. @l := @l + 1 as lvl
  6. FROM (SELECT @r := '1014', @l := 0) vars, dept as h
  7. WHERE @r <> 0) t1
  8. JOIN dept t2
  9. ON t1._id = t2.id
  10. ORDER BY T1.lvl DESC;

代码 @r := 1014 表示查询 id 为 1014 的所有父类

  1. id |name |pid |
  2. ----+------+----+
  3. 1000|总公司 | |
  4. 1002|上海分公司 |1000|
  5. 1013|上海研发部 |1002|
  6. 1014|上海研发一部|1013|

向下递归#

根据⼀个⽗节点查询所有⼦节点(包含⾃⾝)
  1. -- 根据⼀个⽗节点查询所有⼦节点(包含⾃⾝)
  2. SELECT au.id, au.name, au.pid
  3. FROM (SELECT * FROM dept WHERE pid IS NOT NULL) au,
  4. (SELECT @pid := '1002') pd
  5. WHERE FIND_IN_SET(pid, @pid) > 0
  6. AND @pid := concat(@pid, ',', id)
  7. UNION
  8. SELECT id, name, pid
  9. FROM dept
  10. WHERE id = '1002'
  11. ORDER BY id;
  1. id |name |pid |
  2. ----+------+----+
  3. 1002|上海分公司 |1000|
  4. 1013|上海研发部 |1002|
  5. 1014|上海研发一部|1013|
  6. 1015|上海研发二部|1013|
根据多个⽗节点查询所有⼦节点(包含⾃⾝)#
  1. -- 根据多个⽗节点查询所有⼦节点(包含⾃⾝)
  2. SELECT au.id, au.name, au.pid
  3. FROM (SELECT * FROM dept WHERE pid IS NOT NULL) au,
  4. (SELECT @pid := '1002,1005') pd
  5. WHERE FIND_IN_SET(pid, @pid) > 0 and @pid := concat(@pid, ',', id)
  6. UNION
  7. SELECT id, name, pid
  8. FROM dept
  9. WHERE FIND_IN_SET(id, @pid) > 0
  10. ORDER BY id;
  1. id |name |pid |
  2. ----+------+----+
  3. 1002|上海分公司 |1000|
  4. 1005|北京市场部 |1001|
  5. 1012|北京市场一部|1005|
  6. 1013|上海研发部 |1002|
  7. 1014|上海研发一部|1013|
  8. 1015|上海研发二部|1013|

参考
https://www.cnblogs.com/guohu/p/14990788.html

标签: 数据库 sql

本文转载自: https://blog.csdn.net/weixin_54138140/article/details/141917299
版权归原作者 IT民工p10 所有, 如有侵权,请联系我们删除。

“MySQL5.7 递归查询 看这一篇就够了 简单易懂”的评论:

还没有评论