mysql 树结构递归处理
日常开发中我们经常会遇到树形结构数据处理,一般表结构通常会常用id,pid这种设计方案。
之前用oracle、sqlServer数据库,用相应的语法即可获取树形结构数据(oracel:connect by prior ;sqlServer:with...as ...)。
最近一个项目数据库用的是mysql,需求中含有获取树形结构数据的接口,由于之前没怎么用过mysql,于是第一时间就是查看mysql语法,看看有没有类似于oracle或sqlserver的递归语法,结果是没有,后来决定自定义数据库函数(暂时解决了需求)。
1.自定义递归函数
SET FOREIGN_KEY_CHECKS=0; -- ----------------------------
-- Function structure for `getPartyChildOrg`
-- ----------------------------
DROP FUNCTION IF EXISTS `getPartyChildOrg`;
DELIMITER ;;
CREATE DEFINER=`root`@`%` FUNCTION `getPartyChildOrg`(orgid BIGINT) RETURNS varchar(4000) CHARSET utf8
BEGIN
DECLARE oTemp VARCHAR(4000);
DECLARE oTempChild VARCHAR(4000); SET oTemp = '';
SET oTempChild = CAST(orgid AS CHAR); WHILE oTempChild IS NOT NULL
DO
SET oTemp = CONCAT(oTemp,',',oTempChild);
SELECT GROUP_CONCAT(id) INTO oTempChild FROM sub_party_orginfo WHERE logic_delete = 0 and FIND_IN_SET(pid,oTempChild) > 0;
END WHILE;
RETURN oTemp;
END
;;
DELIMITER ;
暂时满足了需求,后期数据量大了,再加上主键生成策略生成的主键长度比较长,函数返回结果长度受VARCHAR最大长度限制,该方案会失效,导致查询的数据不全。
2.自定义存储过程,将查询的结果存放到临时表中。
SET FOREIGN_KEY_CHECKS=0; -- ----------------------------
-- Procedure structure for `findPartyOrgChildList`
-- ----------------------------
DROP PROCEDURE IF EXISTS `findPartyOrgChildList`;
DELIMITER ;;
CREATE DEFINER=`root`@`%` PROCEDURE `findPartyOrgChildList`(IN pid VARCHAR(20))
BEGIN
DECLARE v_org BIGINT(20);
DECLARE done INTEGER DEFAULT 0;
-- 查询结果放入游标中
DECLARE C_org CURSOR FOR SELECT d.id
FROM sub_party_orginfo d
WHERE d.pid = pid;
DECLARE CONTINUE HANDLER FOR NOT found SET done=1;
SET @@max_sp_recursion_depth = 10; -- 传入的组织id写入临时表
INSERT INTO temp_party_org VALUES (pid);
OPEN C_org;
FETCH C_org INTO v_org;
WHILE (done=0)
DO
-- 递归调用,查找下级
CALL findPartyOrgChildList(v_org);
FETCH C_org INTO v_org;
END WHILE;
CLOSE C_org;
END
;;
DELIMITER ; -- ----------------------------
-- Procedure structure for `findPartyOrgList`
-- ----------------------------
DROP PROCEDURE IF EXISTS `findPartyOrgList`;
DELIMITER ;;
CREATE DEFINER=`root`@`%` PROCEDURE `findPartyOrgList`(IN pid BIGINT(20))
BEGIN
DROP TEMPORARY TABLE IF EXISTS temp_party_org;
-- 创建临时表
CREATE TEMPORARY TABLE temp_party_org(id BIGINT(20));
-- 清空临时表数据
DELETE FROM temp_party_org;
-- 发起调用
CALL findPartyOrgChildList(pid); END
;;
DELIMITER ;
mysql 树结构递归处理的更多相关文章
- mysql+mybatis递归调用
递归调用的应用场景常常出现在多级嵌套的情况,比如树形的菜单.下面通过一个简单的例子来实现mysql+mybatis的递归. 数据模型 private Integer categoryId; priva ...
- mysql中递归树状结构<转>
在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点.但很遗憾,在MySQL的目前版本中还没有对应的功能. ...
- mysql类似递归的一种操作进行层级查询
select device_id,device_type,COUNT(1) count from ( select t1.device_id,t1.device_type,DATE_SUB(t1.re ...
- mysql向上递归&向下递归
工作记录 向上递归函数test: BEGIN ); ); SET sTemp = '$'; SET sTempChd =cast(rid as CHAR); WHILE sTempChd is not ...
- sqlserver 树结构递归(向上递归和向下递归)
--获取当前及以下部门 Create proc GetCurrentAndUnderOrg @orgId int as begin WITH cte AS ( SELECT * ,0 AS level ...
- mysql的递归(使用函数)
getChildList: BEGIN #声明两个局部变量 ); ); #初始化局部变量 SET sTemp = ''; #调用cast函数将int转换为char SET sTempChd = roo ...
- JAVA实现查询栏目、类别(菜单)返回树结构(递归)
其中Channel.java是栏目结构,ChannelDto是我自己封装的返回给前端的数据,可以根据自己的来 这个的逻辑就是双重循环遍历每个类别,然后判断如果当前类别是其他类别的父级,那么就把其他类别 ...
- list转换为树结构--递归
public static JSONArray treeMenuList(List<Map<String, Object>> menuList, Object parentId ...
- 递归的实际业务场景之MySQL 递归查询
喜欢就点个赞呗! 源码<--请点击此处查看 引入 当我看到一些评论时,例如下面的样子.我挺好奇这个功能是怎么样做出来的.进过查阅资料,发现这其实是 MySQL 的递归操作.下面就让我操作一下怎么 ...
随机推荐
- 【Oracle/Java】以Insert ALL方式向表中插入百万条记录,耗时9分17秒
由于按一千条一插程序长期无反应,之后改为百条一插方式,运行完发现插入百万记录需要9m17s,虽然比MySQL效率差,但比单条插入已经好不少了. 对Oracle的批量插入语法不明的请参考:https:/ ...
- osg::MatrixTransform 模型基本变换
VCNodeMatrix.h #pragma once #include <osgViewer/Viewer> #include <osgViewer/ViewerEventHand ...
- labelimg data
<annotation> <folder>img_data_box_1500</folder> <filename>798.jpg</filena ...
- 123457123456#0#-----com.threeapp.SuanShuXiaoTianCai01----数学算术小天才
com.threeapp.SuanShuXiaoTianCai01----数学算术小天才
- 123457123456#0#---com.threeapp.ErTongShuXueKoSuan01----儿童宝宝数学口算01
com.threeapp.ErTongShuXueKoSuan01----儿童宝宝数学口算01
- 开启windows ping端口功能
1.打开控制面板,选择程序 2.选择打开和关闭windows功能 3.将Tenet客户端选项勾上 4.运行栏中输入cmd,进入到命令窗口 5.输入命令 ping ip地址 端口号 ...
- ABAP Memory ID
转自:https://blog.csdn.net/lyq123333321/article/details/52659114 (一) Difference Between SAP a ...
- c#子线程执行完怎么通知主线程(转)
定义一个委托实现回调函数 public delegate void CallBackDelegate(string message); 程序开始的时候 //把回调的方法给委托变量 CallBackDe ...
- spark实现wordcount
spark-shell --master yarnsc:val lineRDD=sc.textFile("/test/input/test")lineRDD.collect().f ...
- node.js写巨大的xlsx
一般用node-xlsx写xlsx文件的话局要把数据全部放在内存里面再写到文件里,如果文件很大的话就会导致内存吃不消. 可以使用PySpreadsheet这个npm库,他支持写很大的文件. PySpr ...