欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Mysql自定义函数替代oracle递归算法start with connect by prior

程序员文章站 2024-03-19 19:39:04
...

需求:查询某用户所在部门及其子部门的ID

oracle中的实现:

select depart_id
from t_depart d
start with d.depart_id = (select depart_id from t_user where user_id = 1) connect by d.parent_depart_id = prior d.depart_id

结果:

Mysql自定义函数替代oracle递归算法start with connect by prior

Mysql中没有改递归算法,只能通过自定义函数实现:

自定义函数:

CREATE DEFINER=`root`@`%` FUNCTION `getRecursionList`(rootIds varchar(1000), tableName varchar(30), recursionType varchar(10)) RETURNS varchar(4000) CHARSET utf8
BEGIN 
	-- 函数作用:oralce递归算法start with connect by prior替代函数
	-- 参数说明:rootIds根节点值(如果多个用,号分割) tableName(表名区分哪个表的递归遍历) recursionType递归类型(parent向父节点递归 child向子节点递归)
	DECLARE sList VARCHAR(4000);
	DECLARE sTemp VARCHAR(4000);
	SET sTemp = rootIds;
	SET tableName = lower(tableName);
	SET recursionType = lower(recursionType);
	WHILE sTemp IS NOT NULL DO
		IF (sList IS NOT NULL) THEN
			SET sList = CONCAT(sList,',',sTemp);
		ELSE
			SET sList = CONCAT(sTemp);
		END IF;
		IF (tableName = 't_depart') THEN
			IF (recursionType = 'parent') THEN
				SELECT GROUP_CONCAT(PARENT_DEPART_ID) INTO sTemp FROM T_DEPART WHERE FIND_IN_SET(DEPART_ID, sTemp)>0;
			ELSE
				SELECT GROUP_CONCAT(DEPART_ID) INTO sTemp FROM T_DEPART WHERE FIND_IN_SET(PARENT_DEPART_ID, sTemp)>0;
			END IF;
		ELSEIF (tableName = 't_business') THEN
			IF (recursionType = 'parent') THEN
				SELECT GROUP_CONCAT(PARENT_BUSINESS_ID) INTO sTemp FROM T_BUSINESS WHERE FIND_IN_SET(BUSINESS_ID, sTemp)>0;
			ELSE
				SELECT GROUP_CONCAT(T_BUSINESS) INTO sTemp FROM T_BUSINESS WHERE FIND_IN_SET(PARENT_BUSINESS_ID, sTemp)>0;
			END IF;
		END IF;
	END WHILE;
	RETURN sList; 
END

使用:

SELECT depart_id
FROM t_depart d
WHERE FIND_IN_SET(d.depart_id, getRecursionList((select depart_id from t_user where user_id = 1), 't_depart', 'child'))

结果:

Mysql自定义函数替代oracle递归算法start with connect by prior

批量递归子节点的实现示例:

oracle:

Mysql自定义函数替代oracle递归算法start with connect by prior

Mysql:

Mysql自定义函数替代oracle递归算法start with connect by prior