MySQL查询树形结构的数据
本文共 4,049 字,预计阅读时间 13 分钟
在项目中经常会遇到树形结构的数据,如何去根据需要去查询也显得尤为重要。
其中表结构如下:
CREATE TABLE `s_region` ( `region_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '行政区编码', `region_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '行政区名称', `parent_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '上级行政区编码', `all_parent` varchar(4000) DEFAULT NULL COMMENT '所有父级节点的编码', PRIMARY KEY (`region_code`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
注:all_parent字段可根据实际需求决定是否使用。
添加数据
INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('110000', '北京市', '0', '110000'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('110100', '市辖区', '110000', '110000,110100'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('110101', '东城区', '110100', '110000,110100,110101'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('110102', '西城区', '110100', '110000,110100,110102'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('110105', '朝阳区', '110100', '110000,110100,110105'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('420000', '湖北省', '0', '420000'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('420100', '武汉市', '420000', '420000,420100'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('420103', '江汉区', '420100', '420000,420100,420103'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('420106', '武昌区', '420100', '420000,420100,420106'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('420111', '洪山区', '420100', '420000,420100,420111'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('420115', '江夏区', '420100', '420000,420100,420115'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('420200', '黄石市', '420000', '420000,420200'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('420204', '下陆区', '420200', '420000,420200,420204'); INSERT INTO `cmdp_auth`.`s_region`(`region_code`, `region_name`, `parent_code`, `all_parent`) VALUES ('420222', '阳新县', '420200', '420000,420200,420222');
1)需求1:查询当前节点的所有父级节点信息
set @tempCode='要查询的编码'; SELECT T2.* FROM ( SELECT @R AS rid, ( SELECT @R := parent_code FROM s_region WHERE region_code = rid ) AS parent_code, @L := @L + 1 AS LVL FROM ( SELECT @R := @tempCode, @L := 0) VARS, s_region h WHERE @R >= 0 ) T1 INNER JOIN s_region T2 ON T1.rid = T2.region_code ORDER BY T1.LVL DESC;
其中@tempCode为临时变量,是实际的mybatis的xml中,直接使用变量替换即可。
如查询北京市西城区的所有父级信息,查询结果如下:
2)需求2:查询当前节点的所有子级节点信息
set @tempCode='要查询的编码' ; select t3.* from ( select t1.*, if(find_in_set(parent_code, @pids) > 0, @pids := concat(@pids, ',', region_code), if (t1.region_code = @tempCode,@tempCode,0)) as ischild from ( select t.* from s_region t ) t1, (select @pids := @tempCode) t2 ) t3 where ischild != 0
如要查询湖北省武汉市的所有子节点:
当然上述在查询子节点时,当树形结构子节点数据太大时,查询效率会降低
这里字段all_arent就派上用场了,这个字段存的是所有父级和自身节点的编码,便于查询。此字段需要根据实际需求去决定是否使用,因为这种方式采用的是使用空间换时间。树形结构的数据类似一棵树,子节点是横向与扩展,会存在子节点的数据非常庞大。而此字段存储的是所有的父节点的编码,只要树的深度不是很大,那么其内容就不会很大。
select * from s_region where find_in_set('420100',all_parent)
当然提高了查询的效率,那么在数据更新时,是需要根据实际情况去更新all_parent字段的值。
就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2021-10-14 MySQL create table as与create table like对比
2019-10-14 SpringBoot基础