Mysql 5 递归

最近在弄SQL server 转MySQL,需要将SQL server 的函数转成MySQL 函数,SQL server 用到了

with cte as ()select * cte 

这是一个递归函数

WITH cte AS (
		SELECT p.*
		FROM
		pt_permission p
		WHERE 
		( p.sys_id = 0 or p.sys_id = #sysId# ) and /* 20160627 cyx*/
		p.parent_id = #parentId# and p.disabled=0 and permission_code not IN('PT_PROJECT_LIST','PT_USER_ADMINLIST','PT_EQU_ENTITY_LIST','DATA_DTU_NEW','DATA_DTU_LAST','DATA_XT_NEW','PT_USER_EXCEL','PT_SMS_COUNT')
		UNION ALL
		SELECT pe.*
		FROM
		pt_permission pe
		INNER JOIN cte c ON c.id = pe.parent_id and pe.disabled=0
		) 
		SELECT
			*
		FROM
			cte;

现在要转成MySQL 实现递归,不过目前我们公司用的MySQL 5 没有with cte as 函数,MySQL 8 倒是有了with cte as ,不过现在要自己实现MySQL 递归。

一,自定义函数

1.1 创建函数 

        

CREATE DEFINER=`root`@`localhost` FUNCTION `get_value_of`(sys_id varchar(1000)) RETURNS varchar(1000) CHARSET utf8
begin 
 declare ids varchar(1000) default ''; 
 declare tempids varchar(1000); 
 
 set tempids = sys_id; 
 while tempids is not null do 
  set ids = CONCAT_WS(',',ids,tempids);
  select GROUP_CONCAT(id) into tempids from pt_permission where FIND_IN_SET(parent_id,tempids)>0;
 end while; 
 return ids; 
end
  • 自定义函数名称为:get_value_of
  • pt_permission:表名称
  • sys_id:参数

1.2 根据上面SQL server 的语句逻辑,编写sql

SELECT DISTINCT * from pt_permission pe WHERE FIND_IN_SET(id,get_value_of(

	(SELECT
		GROUP_CONCAT(p.id )  
	FROM
		pt_permission p 
	WHERE
	 p.sys_id = 0 or p.sys_id = '2'  -- 参数p.sys_id
	and 
		p.parent_id = '0' -- 参数p.parent_id
		AND p.disabled = 0 
		AND permission_code NOT IN ( 'PT_PROJECT_LIST', 'PT_USER_ADMINLIST', 'PT_EQU_ENTITY_LIST', 'DATA_DTU_NEW', 'DATA_DTU_LAST', 'DATA_XT_NEW', 'PT_USER_EXCEL', 'PT_SMS_COUNT' ) 
		)

)) AND pe.disabled = 0 

1.3 思路

        首选是梳理你的递归,是向上递归,还是向下递归,然后梳理递归的参数,参数是一个值,还是一个数组,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MySQL 5版本可以使用递归查询,但需要使用MySQL的自连接和临时表(Temporary Table)来实现。 下面是一个示例查询: 假设有一个员工表(employees),包含员工ID(id)和直接上级ID(manager_id)两个字段,现在要查找一个员工的所有上级。 首先,需要创建一个临时表来存储递归查询的结果。可以使用以下语句创建一个空的临时表(temp_table): ``` CREATE TEMPORARY TABLE temp_table (id INT, manager_id INT); ``` 然后,使用INSERT INTO SELECT语句将指定员工的直接上级插入到临时表中: ``` INSERT INTO temp_table SELECT id, manager_id FROM employees WHERE id = {指定员工ID}; ``` 接下来,使用循环语句来递归查询所有上级。可以使用WHILE循环和MySQL的自连接来实现: ``` SET @id = {指定员工ID}; WHILE @id > 0 DO INSERT INTO temp_table SELECT e.id, e.manager_id FROM employees e JOIN temp_table t ON e.id = t.manager_id WHERE e.id <> t.id AND e.manager_id IS NOT NULL; SET @id = (SELECT manager_id FROM employees WHERE id = @id); END WHILE; ``` 最后,使用SELECT语句从临时表中获取所有上级的信息: ``` SELECT * FROM temp_table; ``` 完整的查询语句如下: ``` CREATE TEMPORARY TABLE temp_table (id INT, manager_id INT); INSERT INTO temp_table SELECT id, manager_id FROM employees WHERE id = {指定员工ID}; SET @id = {指定员工ID}; WHILE @id > 0 DO INSERT INTO temp_table SELECT e.id, e.manager_id FROM employees e JOIN temp_table t ON e.id = t.manager_id WHERE e.id <> t.id AND e.manager_id IS NOT NULL; SET @id = (SELECT manager_id FROM employees WHERE id = @id); END WHILE; SELECT * FROM temp_table; ``` 注意,这种方法存在性能问题,如果数据量较大,可能会导致查询时间过长或内存溢出。因此,建议在实际使用时进行优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vegetari

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值