今天没事看FIND_IN_SET函数功能时,发现曾老师的一篇用MySQL做递归层次查询的文章,功能很实用,还涉及到了Mysql函数,比较有意思,就试着写了下该函数,哈哈,以前没用过函数,见笑了。在此,也感谢曾老师了,呵呵,还有每个热爱分享的IT人!
表结构基本和曾老师的一样,如下:
CREATE TABLE `tree` (
`id` int(11) NOT NULL,
`name` varchar(50) DEFAULT NULL,
`pid` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入数据如下:
INSERT INTO `tree` VALUES ('1', 'A', '0');
INSERT INTO `tree` VALUES ('2', 'B', '1');
INSERT INTO `tree` VALUES ('3', 'C', '1');
INSERT INTO `tree` VALUES ('4', 'D', '2');
INSERT INTO `tree` VALUES ('5', 'E', '2');
INSERT INTO `tree` VALUES ('6', 'F', '3');
INSERT INTO `tree` VALUES ('7', 'G', '6');
INSERT INTO `tree` VALUES ('8', 'H', '0');
INSERT INTO `tree` VALUES ('9', 'I', '8');
INSERT INTO `tree` VALUES ('10', 'J', '8');
INSERT INTO `tree` VALUES ('11', 'K', '8');
INSERT INTO `tree` VALUES ('12', 'L', '9');
INSERT INTO `tree` VALUES ('13', 'M', '9');
INSERT INTO `tree` VALUES ('14', 'N', '12');
INSERT INTO `tree` VALUES ('15', 'O', '12');
INSERT INTO `tree` VALUES ('16', 'P', '15');
INSERT INTO `tree` VALUES ('17', 'Q', '15');
递归层次查询函数:
CREATE DEFINER = `root`@`localhost` FUNCTION `NewProc`(`rId` int)
RETURNS varchar(500)
BEGIN
#声明两个局部变量
DECLARE sTemp VARCHAR(500);
DECLARE stempChd VARCHAR(500);
#初始化局部变量
SET sTemp = '$';
#调用cast函数将int转换为char
SET stempChd = CAST(rId 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 tree where FIND_IN_SET(pid,stempChd)>0;
END WHILE;
RETURN sTemp;
END;
这个是用Navicat for MySQL生成的,BEGIN和END之间是真正的函数体,每条完整的语句都要以分号;结束,否则会报错。这个函数功能是返回以给定参数作为父节点的所有子节点的字符串,哈哈,当然会多个$的。
使用示例:
mysql> select getChildLst(1);
+-----------------+
| getChildLst(1) |
+-----------------+
| $,1,2,3,4,5,6,7 |
+-----------------+
1 row in set (0.00 sec)
==========================
mysql> select * from treeNodes
-> where FIND_IN_SET(id, getChildLst(1));
+----+----------+------+
| id | name | pid |
+----+----------+------+
| 1 | A | 0 |
| 2 | B | 1 |
| 3 | C | 1 |
| 4 | D | 2 |
| 5 | E | 2 |
| 6 | F | 3 |
| 7 | G | 6 |
+----+----------+------+
7 rows in set (0.01 sec)
貌似oracle中有可以直接实现该功能的函数CONNECT BY,没用过,哈哈。。。