【DataBase】MySQL根据父节点查询下面的所有子节点
表结构如下:
/*
Navicat Premium Data Transfer Source Server : 主机
Source Server Type : MySQL
Source Server Version : 80023
Source Host : localhost:3308
Source Schema : my-info Target Server Type : MySQL
Target Server Version : 80023
File Encoding : 65001 Date: 20/06/2021 10:09:06
*/ SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0; -- ----------------------------
-- Table structure for tt_wechat_org
-- ----------------------------
DROP TABLE IF EXISTS `tt_wechat_org`;
CREATE TABLE `tt_wechat_org` (
`ID` int NOT NULL COMMENT '微信主键',
`NAME` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '部门名称',
`NAME_EN` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '部门英文名称',
`PARENT_ID` int NOT NULL COMMENT '父部门ID',
`OEDER` int NOT NULL COMMENT '在父部门中的次序值',
`CREATED_BY` bigint NULL DEFAULT NULL,
`CREATED_AT` datetime NULL DEFAULT NULL,
`UPDATED_BY` bigint NULL DEFAULT NULL,
`UPDATED_AT` datetime NULL DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信组织部门表' ROW_FORMAT = Dynamic;
部门,或者称为组织结构,也是一个树状的层级结构:
业务需求需要从某一个部门开始获取下面的所有子部门
这样来查询每个部门下面的人员,用来查询人员的一些字段
先查询根节点开始,一般根节点的parent_id设置为0,即表示没有上一级的节点了
SELECT * FROM tt_wechat_org WHERE parent_id = 0
输出
+-----------+----------------------------------------------+---------+-----------+-----------+------------+---------------------+------------+---------------------+
| ID | NAME | NAME_EN | PARENT_ID | OEDER | CREATED_BY | CREATED_AT | UPDATED_BY | UPDATED_AT |
+-----------+----------------------------------------------+---------+-----------+-----------+------------+---------------------+------------+---------------------+
| 1 | 江铃汽车股份有限公司乘用车销售服务上海分公司 | | 0 | 100000000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 999999999 | 总部 | | 0 | 1 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
+-----------+----------------------------------------------+---------+-----------+-----------+------------+---------------------+------------+---------------------+
2 rows in set (0.03 sec)
再向下查询又会有更多的子节点:
SELECT * FROM tt_wechat_org WHERE parent_id = 1;
输出:
+-----+-----------------------------+---------+-----------+-----------+------------+---------------------+------------+---------------------+
| ID | NAME | NAME_EN | PARENT_ID | OEDER | CREATED_BY | CREATED_AT | UPDATED_BY | UPDATED_AT |
+-----+-----------------------------+---------+-----------+-----------+------------+---------------------+------------+---------------------+
| 2 | 销售及渠道 | | 1 | 100002000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 3 | 数字化 | | 1 | 99999000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 4 | 售后 | | 1 | 99998000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 5 | 市场 | | 1 | 99999500 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 6 | 产品市场 | | 1 | 99996000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 7 | 采购&财务 | | 1 | 99992125 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 45 | 客服支持(DMS/企业微信/商城) | | 1 | 99992250 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 46 | 总经办 | | 1 | 100003000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 49 | 经销商 | | 1 | 99994125 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 240 | 共享素材管理组 | | 1 | 99991125 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 282 | 信息部 | | 1 | 99990125 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 283 | 区域营销广代商 | | 1 | 99989125 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 289 | 临时 | | 1 | 99989625 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 528 | BCG | | 1 | 99988125 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
+-----+-----------------------------+---------+-----------+-----------+------------+---------------------+------------+---------------------+
14 rows in set (0.06 sec)
如此往复,直到最后没有节点可以查询出来了
1、一个SQL只能查询一次
2、每次查询只能查询出下一级节点的ID
3、下一级节点的ID是下个下一级的Parent_ID
所以需要一个可以递归的SQL
SELECT
id,
NAME,
parent_id
FROM
( SELECT * FROM products ORDER BY parent_id, id ) products_sorted,
( SELECT @pv := '19' ) initialisation
WHERE
find_in_set( parent_id, @pv )
AND length(
@pv := concat( @pv, ',', id ))
如果需求要求一些职员是越级的,例如他既是总监,又是经理,管东区又管西区的这种
就需要给他查询多个部门的ID
@pv := '19, 11'
这样也能支持
不过我实现需求的时候还是没采用这种方式,我是用IN关键字做子查询嵌套
一般来说层级关系是固定不变的
例如这一段,给的是大区,然后查询下面所有的分店:
SELECT * FROM tt_wechat_org WHERE parent_id IN(
SELECT id FROM tt_wechat_org WHERE parent_id IN(
SELECT id FROM tt_wechat_org WHERE parent_id IN(8, 10)
)
)
输出:
+-----+----------------------+---------+-----------+-----------+------------+---------------------+------------+---------------------+
| ID | NAME | NAME_EN | PARENT_ID | OEDER | CREATED_BY | CREATED_AT | UPDATED_BY | UPDATED_AT |
+-----+----------------------+---------+-----------+-----------+------------+---------------------+------------+---------------------+
| 51 | 成都万星 | | 95 | 100006062 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 55 | 新疆天汇福达 | | 145 | 100002000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 57 | 曲靖明福 | | 157 | 100005312 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 59 | 克拉玛依天宇兴合 | | 145 | 100001750 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 62 | 达州骏骥 | | 95 | 100006000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 63 | 新疆龙泽源 | | 145 | 100001875 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 64 | 德阳万星 | | 95 | 100006125 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 65 | 保山金运 | | 157 | 100005000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 73 | 上海科达 | | 225 | 100000000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 74 | 喀什秋林 | | 145 | 100002375 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 77 | 四川福顺 | | 95 | 100006031 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 80 | 云南明福 | | 157 | 100005500 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 81 | 江西江铃 | | 115 | 100001000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 84 | 昆明健中冈 | | 157 | 100006000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 85 | 龙山万福 | | 157 | 100005125 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 86 | 南充骏耀 | | 95 | 100006375 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 88 | 绵阳万鸿 | | 95 | 100006500 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 96 | 遂宁新清巍 | | 95 | 100002250 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 102 | 浙江江铃嘉兴分公司 | | 101 | 100000000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 110 | 莆田江福 | | 109 | 100000000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 111 | 浙江江铃绍兴分公司 | | 101 | 99999000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 113 | 重庆安博两江分公司 | | 112 | 100000000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 116 | 江西福铃 | | 115 | 100000000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 122 | 湖州万永 | | 101 | 100000500 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 123 | 福州丰骏 | | 109 | 99999093 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 128 | 贵州万佳 | | 127 | 100000000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 129 | 重庆怡之铃 | | 112 | 100000500 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 132 | 兰州赛福 | | 131 | 100000000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 133 | 慈溪友铃 | | 101 | 99999500 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 134 | 贵州万福 | | 127 | 99999000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 146 | 新疆丰骏福瑞 | | 145 | 100002312 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 151 | 宁夏福立升 | | 150 | 100000000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 158 | 文山惠福昇 | | 157 | 100003500 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 160 | 九江江福 | | 115 | 99999000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 163 | 龙岩丰骏福瑞 | | 109 | 99999031 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 168 | 四川中润通汇 | | 95 | 100004000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 174 | 阿克苏秋林 | | 145 | 100003000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 180 | 宁波顺福 | | 101 | 99998125 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 185 | 伊犁尊福 | | 145 | 100001812 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 188 | 泉州国骏 | | 109 | 99999500 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 192 | 嘉峪关良志 | | 131 | 99999000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 194 | 青海嘉悦 | | 193 | 100000000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 196 | 南平华骏 | | 109 | 99999007 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 198 | 漳州华骏天瑞 | | 109 | 99999062 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 199 | 甘肃顺铃 | | 131 | 99998000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 202 | 浙江万捷 | | 101 | 100001000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 203 | 丽水福鑫 | | 101 | 99999250 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 204 | 重庆安福新牌坊分公司 | | 112 | 100001000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 206 | 厦门丰骏福瑞 | | 109 | 99999250 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 209 | 丽江金鸿铭 | | 157 | 100004000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 212 | 上饶星顺 | | 115 | 99998000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 217 | 眉山清巍 | | 95 | 100002500 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 218 | 义乌瑞鑫 | | 101 | 99998250 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 239 | 巴州龙跃 | | 145 | 100002500 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 243 | 温州金跃 | | 101 | 99998500 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 472 | 宁德丰汇 | | 109 | 99999125 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 474 | 三明福元 | | 109 | 99999015 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 488 | 广安骏图 | | 95 | 100007000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 515 | 叶城华联 | | 145 | 99993000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 527 | 贵州林荣 | | 127 | 99998000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 531 | 赣州铃卡 | | 115 | 99996000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 539 | 西藏睿欧 | | 227 | 99999000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 540 | 四川江铃西昌分公司 | | 95 | 100003000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 541 | 宜宾盛晖 | | 95 | 100002125 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 544 | 浙江江铃临安 | | 101 | 99987000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 545 | 台州铭致 | | 101 | 99986000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
| 550 | 台州福奥 | | 101 | 99985000 | NULL | 2021-06-08 14:47:40 | NULL | 2021-06-08 14:47:40 |
+-----+----------------------+---------+-----------+-----------+------------+---------------------+------------+---------------------+
67 rows in set (0.25 sec)
用递归SQL的结果似乎也是一样的:
SELECT
*
FROM
( SELECT * FROM tt_wechat_org ORDER BY parent_id, id ) products_sorted,
( SELECT @pv := '8,10' ) initialisation
WHERE
find_in_set( parent_id, @pv )
AND length(
@pv := concat( @pv, ',', id )) ORDER BY id
2021年6月26日 21点57分 更新部分:
上一个SQL有一定的问题,例如查询特定层级的ID会失效
后来是改成这个样子实现的:
SELECT
TT.id,
TT.NAME
FROM (
SELECT
DISTINCT c2.id,
c2.NAME,
c2.NAME_EN,
c2.parent_id,
c1.level-1 LEVEL
FROM (
SELECT
@ids AS _ids,
( SELECT @ids := GROUP_CONCAT(id) FROM tt_wechat_org WHERE FIND_IN_SET(parent_id, @ids)) AS cids,
@l := @l+1 AS LEVEL
FROM
tt_wechat_org,
(SELECT @ids :='49', @l := 0 ) b
WHERE @ids IS NOT NULL
) c1,
tt_wechat_org c2
WHERE FIND_IN_SET(c2.id, c1._ids) ORDER BY LEVEL , id
) TT
过了一周准备上线,结果生产库用的MySQL8
给爷整无语了,现在叫我们去改业务,8的话容易了,有专用的WITH CURSIVE去写
使用MySQL8的WITH RECURSIVE
WITH RECURSIVE cte AS(
SELECT a.id, a.parent_id,a.name FROM tt_wechat_org a WHERE a.id='49'
UNION ALL
SELECT k.id, k.parent_id,k.name FROM tt_wechat_org k INNER JOIN cte c ON c.id = k.parent_id
) SELECT id,NAME,parent_id FROM cte
改了之后,能跑起来就算赢
测试了之后发现,速度比5.7的快,不知道是网络原因还是8版本的性能好
【DataBase】MySQL根据父节点查询下面的所有子节点的更多相关文章
- MySQL中进行树状所有子节点的查询 . mysql根据父id 查询所有的子id
		
在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点.但很遗憾,在MySQL的目前版本中还没有对应的功能. ...
 - SQL 递归查询(根据指定的节点向上获取所有父节点,向下获取所有子节点)
		
--------------------01.向上查找所有父节点-----------------WITH TEMP AS (SELECT * FROM CO_Department WHERE ID= ...
 - mysql 根据父id查询下级所有数据
		
select id,apply_resource_name from ( select t1.id,t1.apply_resource_name, if(find_in_set(parent_id, ...
 - SQL查询树形结构的所有子节点
		
如下一张表test:id name pid----------- ---------- -----------1 电器 NULL2 家电 13 冰箱 24 洗衣机 25 电脑 16 笔记本 57 平板 ...
 - [转]Oracle查询树形数据的叶节点和子节点
		
oracle 9i判断是叶子或根节点,是比较麻烦的一件事情,SQL演示脚本如下: --表结构-- DROP TABLE idb_hierarchical; create TABLE idb_hiera ...
 - bootstrap-treeview 如何实现全选父节点下所有子节点及反选
		
转(https://www.augsky.com/992.html) 选中父节点时,父节点下所有子节点也都全部选中 1,HTML代码 <h2>TreeView Checkable</ ...
 - 【转】 oracle 层次查询判断叶子和根节点
		
Oracle 9i判断是叶子或根节点,是比较麻烦的一件事情,SQL演示脚本如下: DROP TABLE idb_hierarchical; create TABLE idb_hierarchical ...
 - MySql 利用函数 查询所有子节点
		
前提:mysql 函数 find_in_set(str,strlist), cast(value as type) 一.find_in_set(str,strlist):如果字符串str是在的 ...
 - MySQL中进行树状所有子节点的查询
		
在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点.但很遗憾,在MySQL的目前版本中还没有对应的功能. ...
 - SqlServer父节点与子节点查询及递归
		
在最近老是用到这个SQL,所以记下来了: 1:创建表 CREATE TABLE [dbo].[BD_Booklet]( [ObjID] [int] IDENTITY(1,1) NOT NULL, [P ...
 
随机推荐
- kettle从入门到精通 第二十七课 邮件发送
			
1.我们平常在做数据同步的时候,担心转换或者job没有正常运行,需要加上监控机制,这个时候就会用到邮件功能. 下图是一个简单的测试邮件发送功能的转换.在kettle.properties文件中设置邮件 ...
 - k8s 安装ingress nginx controller 并部署.net core ingress服务
			
k8s 安装ingress nginx controller 并部署.net core ingress服务 本地k8s集群概览 192.168.28.132 k8smaster 192.168.28. ...
 - Go版RuoYi
			
RuoYi-Go https://github.com/Kun-GitHub/RuoYi-Go 1. 关于我 个人介绍 2. 介绍 后端用Go写的RuoYi权限管理系统 (功能正在持续实现)后端 G ...
 - PowerBI_一分钟了解POWERBI计算组_基础运用篇(一)
			
在第一篇计算组的文章中,给大家介绍了,POWERBI的计算组功能的基本概念和作用. 本文,旨在通过简单案例,介绍计算组功能的具体应用场景. 没有看过第一篇的同学,可以先简单过一下第一篇,补齐一下概念和 ...
 - 哎,被这个叫做at least once的玩意坑麻了。
			
你好呀,我是歪歪. 前几天遇到一个生产问题,同一个数据在数据库里面被插入了两次,导致后续处理出现了一些问题. 当时我们首先检讨了自己,没有做好幂等校验.甚至还发现了一个低级错误:对应的表,针对订单号, ...
 - Merry Christmas 礼物
			
Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` Merry Christmas 礼物 日期:2020-12 ...
 - python webdriver.remote远程创建火狐浏览器会话报错,Unable to create new service: GeckoDriverService
			
问题: 使用selenium.webdriver.remote,远程指定地址的浏览器,并创建会话对象:创建火狐浏览器会话时,报错,错误信息如下: Message: Unable to create n ...
 - python利用公私钥加解密
			
小贴士 这里不再赘述公私钥的生成过程.可以利用OpenSSL进行生成. 加密代码 #!/usr/bin/python #加密 #conda install pycrypto #提前安装模块 impor ...
 - 【VyOS-开源篇-3】- container for vyos 搭建 Halo 博客-vyos-开源篇
			
文章说明:介绍在vyos软路由上配置container容器,vyos最新滚动版1.5已经支持在vyos命令行中启动docker容器,在vyos 官网介绍是说1.3版本之后就都有这个功能了,如果你的版本 ...
 - 使用Swig转换C++到别的编程语言
			
项目github地址: aoce 设定aoce能分别与UE4/Unity3D/android demo对接,就这三来看,分别是C++/C#/java三种语言. C++导出给别的语言使用,一般来说,分为 ...