mysql with ... as (...) 遞歸查詢 改用存儲過程實現


## 找出所有后代數據


with getTree as (
       select parent_id, id from a where a.id = #{id};
       UNION all
       select a.parent_id, a.id from a inner join getTree on a.parent_id = getTree.id
)


delimiter $$
DROP PROCEDURE IF EXISTS findTreeList;
DROP PROCEDURE IF EXISTS getTreeResult;
CREATE PROCEDURE `findTreeList`( in id varchar(50) )
BEGIN
DECLARE child_id VARCHAR(50) DEFAULT '';
DECLARE done INTEGER DEFAULT 1;
DECLARE cur CURSOR FOR
-- 對應的遞歸查詢,由遞歸語句改來:select a.parent_id, a.id from a inner join getTree on a.parent_id = getTree.id
-- 此處遞歸方法主要是找好父子級對應關系,“`findTreeList`( in id varchar(50) )”此參數 id 便是父級id, 匹配的便是子級的parent_id
SELECT a.id FROM a WHERE a.parent_id = id;
DECLARE CONTINUE HANDLER FOR NOT found SET done=0;
INSERT INTO tmp VALUES (tree_id);
SET @@max_sp_recursion_depth = 50;
OPEN cur;
FETCH cur INTO child_id;
WHILE (done=1) DO
CALL findTreeList(child_id);
FETCH cur INTO child_id;
END WHILE;
CLOSE cur;
END;

CREATE PROCEDURE `getTreeResult`( IN id VARCHAR(50) )
DETERMINISTIC
BEGIN
DROP TEMPORARY TABLE IF EXISTS tmp;
-- 結果保存在臨時表中
CREATE TEMPORARY TABLE tmp(tree_id VARCHAR(50));
DELETE FROM tmp;
set @tree_id = (SELECT tree_id FROM i_file_type WHERE is_enabled =1 and i_file_type.file_type_id = file_type_id);
-- 開始遞歸
CALL findTreeList(@tree_id);
-- 可以在此處利用臨時表的結果,寫其他查詢語句
select * from a where a.id = tmp.id;
END;

CALL getTreeResult(#{id});
DROP TEMPORARY TABLE IF EXISTS tmp;
DROP PROCEDURE IF EXISTS findTreeList;
DROP PROCEDURE IF EXISTS getTreeResult;
$$
delimiter ;

 

參考:

https://www.cnblogs.com/sunliyuan/p/13582391.html

https://www.cnblogs.com/loong-hon/p/11003189.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM