在做一个部门组织结构的查询时因为mysql没有oracle的递归查询方法,所以需要自己新建函数或存储过程。
实现递归查询的方式有两种,在都尝试成功后记录下来。
函数
BEGIN
DECLARE sTemp VARCHAR(4000);
DECLARE sTempChd VARCHAR(4000);
SET sTemp = ‘$’;
SET sTempChd = cast(pid as char);
WHILE sTempChd is not NULL DO
SET sTemp = CONCAT(sTemp,’,’,sTempChd);
SELECT group_concat(id) INTO sTempChd FROM sys_group where FIND_IN_SET(parent_id,sTempChd)>0;
END WHILE;
return sTemp;
END
因为函数只是返回一个值,也只是对一些值的操作,操作形式也相对比较简单易看懂
返回结果是以字段的形式返回所有子节点以,分割
$,1,2,3,16c212,4,5
匹配时使用FIND_IN_SET 即可按逗号精确匹配,不过FIND_IN_SET会引起全表查询
存储过程
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE id varchar(255);
–找到id为传入的pid的存入游标
DECLARE cur1 CURSOR FOR SELECT t.id FROM sys_group t WHERE t.parent_id=pid;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
set max_sp_recursion_depth = 255;
OPEN cur1;
read_loop: LOOP
–取出游标放入id
FETCH cur1 INTO id;
IF done THEN
LEAVE read_loop;
END IF;
–存进临时表
INSERT INTO temp_results values ( id, pid);
–递归调用
call getChildrenList(id);
END LOOP;
CLOSE cur1;
END
存储过程相对复杂一些,涉及到临时表之类的,所以用的时候还需要对临时表进行清空
存储过程调用后在临时表产生的数据如下
不含最原始的节点
测试
测试SQL如下:
delete from temp_results;
call getChildrenList(‘1’);
select b.id,b.group_name,t.* from sys_account t
left join sys_group b on b.id = t.group_id
where b.id = ‘1’ or EXISTS (select id from temp_results where b.id = id ) ;
结果如下:
成功找到部门id下所有的节点账号