Mysql遞迴獲取某個父節點下面的所有子節點和子節點上的所有父節點
阿新 • • 發佈:2018-12-12
在MySQL中自定義函式來實現遞迴獲取所有子節點,該方式的優點是可以減少java程式碼量,缺點是:1.不好維護;2.拼接的欄位太長的時候,自定義函式的返回值可能容量不夠,此時可以定義為text等大容量型別;3:show variables like 'group_concat_max_len' 檢視group_concat的容量為1024 ,具體內容檢視:https://blog.csdn.net/world_ding/article/details/54286862
。還有一個注意點,在生產環境中要給自定義的函式分配許可權,不然可能會沒有許可權請求這個自定義的函式。
1.MySQL表結構和資料
/* Navicat MySQL Data Transfer Source Server : localhost_3306 Source Server Version : 50712 Source Host : localhost:3306 Source Database : test Target Server Type : MYSQL Target Server Version : 50712 File Encoding : 65001 Date: 2018-04-13 12:47:42 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for treenodes -- ---------------------------- DROP TABLE IF EXISTS `treenodes`; CREATE TABLE `treenodes` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nodename` varchar(50) DEFAULT NULL, `pid` int(11) DEFAULT '0', `text` text, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of treenodes -- ---------------------------- INSERT INTO `treenodes` VALUES ('1', 'A', '0', null); INSERT INTO `treenodes` VALUES ('2', 'B', '1', null); INSERT INTO `treenodes` VALUES ('3', 'C', '1', null); INSERT INTO `treenodes` VALUES ('4', 'D', '2', null); INSERT INTO `treenodes` VALUES ('5', 'E', '2', null); INSERT INTO `treenodes` VALUES ('6', 'F', '3', null); INSERT INTO `treenodes` VALUES ('7', 'G', '6', null); INSERT INTO `treenodes` VALUES ('8', 'H', '0', null); INSERT INTO `treenodes` VALUES ('9', 'I', '8', null); INSERT INTO `treenodes` VALUES ('10', 'J', '8', null); INSERT INTO `treenodes` VALUES ('11', 'K', '8', null); INSERT INTO `treenodes` VALUES ('12', 'L', '9', null); INSERT INTO `treenodes` VALUES ('13', 'M', '9', null); INSERT INTO `treenodes` VALUES ('14', 'N', '12', null); INSERT INTO `treenodes` VALUES ('15', 'O', '12', null); INSERT INTO `treenodes` VALUES ('16', 'P', '15', null); INSERT INTO `treenodes` VALUES ('17', 'Q', '15', null); INSERT INTO `treenodes` VALUES ('18', '一級機構', '7', null); INSERT INTO `treenodes` VALUES ('19', '二級機構', '18', null); INSERT INTO `treenodes` VALUES ('20', '三級機構', '19', null); INSERT INTO `treenodes` VALUES ('21', '銷售經理', '20', null); INSERT INTO `treenodes` VALUES ('22', '銷售經理2', '21', null); INSERT INTO `treenodes` VALUES ('23', '代理人', '22', null); INSERT INTO `treenodes` VALUES ('24', '代理人', '22', null); INSERT INTO `treenodes` VALUES ('25', '不該出現', null, null);
2.自定義獲取某個父節點下面的所有子節點的函式
CREATE FUNCTION `getChildList`(rootId INT) RETURNS varchar(1000) BEGIN #宣告兩個區域性變數 DECLARE sTemp VARCHAR(1000); DECLARE sTempChd VARCHAR(1000); #初始化區域性變數 SET sTemp = '$'; #呼叫cast函式將int轉換為char SET sTempChd =cast(rootId as CHAR); #遞迴拼接 WHILE sTempChd is not null DO #儲存每次遞迴結果 SET sTemp = concat(sTemp,',',sTempChd); #將引數作為pid,然後查詢其子id,然後將子id作為pid, #查詢以子id為pid的子id,依次迴圈下去,直到所有節點都為葉子節點 SELECT group_concat(id) INTO sTempChd FROM treeNodes where FIND_IN_SET(pid,sTempChd)>0; END WHILE; RETURN sTemp; END #測試 select * from treenodes where FIND_IN_SET(id,getChildList(20));
3.自定義獲取子節點上的所有父節點函式
CREATE FUNCTION `getParList`(rootId INT)
RETURNS varchar(1000)
BEGIN
DECLARE sTemp VARCHAR(1000);
DECLARE sTempPar VARCHAR(1000);
SET sTemp = '';
SET sTempPar =rootId;
#迴圈遞迴
WHILE sTempPar is not null DO
#判斷是否是第一個,不加的話第一個會為空
IF sTemp != '' THEN
SET sTemp = concat(sTemp,',',sTempPar);
ELSE
SET sTemp = sTempPar;
END IF;
SET sTemp = concat(sTemp,',',sTempPar);
SELECT group_concat(pid) INTO sTempPar FROM treenodes where pid<>id and FIND_IN_SET(id,sTempPar)>0;
END WHILE;
RETURN sTemp;
END
#測試
select * from treenodes where FIND_IN_SET(id,getParList(15));
4.刪除自定義的函式
DROP FUNCTION `getChildList`;