最近在做项目时,需要用到mysql递归查询,网上搜索关于递归查询的博客有很多,但是多多少少都有些坑,在这里,自己将它重新整理一下,避免自己踩坑,也方便大家遇到这样的问题。让技术人员能够快速的解决问题。
CREATE DATABASE IF NOT EXISTS `db_recursive`;
USE `db_recursive`;
-- Table structure for table `t_tree`
DROP TABLE IF EXISTS `t_tree`;
SET character_set_client = utf8mb4 ;
CREATE TABLE `t_tree` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
`pid` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
LOCK TABLES `t_tree` WRITE;
INSERT INTO `t_tree` VALUES (1,'江苏省',0),(2,'南京市',1),(3,'栖霞区',2),(4,'江宁区',2),
(5,'玄武区',2),(6,'徐州市',1),(7,'铜山区',6),(8,'泉山区',6);
UNLOCK TABLES;
DROP FUNCTION IF EXISTS `getChildrenBySingleContainSelf`;
delimiter //
CREATE FUNCTION `getChildrenBySingleContainSelf`(rootId INT)
RETURNS varchar(1024)
BEGIN
DECLARE sTemp VARCHAR(1024);
DECLARE sTempChd VARCHAR(1024);
SET sTemp = '$';
SET sTempChd = cast(rootId as CHAR);
WHILE sTempChd is not null DO
SET sTemp = concat(sTemp, ',', sTempChd);
SELECT group_concat(id) INTO sTempChd FROM t_tree where FIND_IN_SET(pid, sTempChd) > 0;
END WHILE;
RETURN sTemp;
END;
//
SELECT * FROM t_tree WHERE FIND_IN_SET(id, `getChildrenBySingleContainSelf`(2));
1.getChildrenBySingleContainSelf:方法名;
2.delimiter:使用DECLARE前需要此关键字,不然SQL会报错;
3.rootId:参数
4.id:表主键id字段
5.t_tree:创建的表名
6.pid:上级ID字段
DROP FUNCTION IF EXISTS `getChildrenBySingle`;
delimiter //
CREATE FUNCTION `getChildrenBySingle`(rootId INT)
RETURNS varchar(1024)
BEGIN
DECLARE sTemp VARCHAR(1024);
DECLARE sTempChd VARCHAR(1024);
SET sTemp = '$';
SET sTempChd = cast(rootId as CHAR);
WHILE sTempChd is not null DO
SET sTemp = concat(sTemp, ',', sTempChd);
SELECT group_concat(id) INTO sTempChd FROM t_tree where FIND_IN_SET(pid, sTempChd) > 0;
END WHILE;
RETURN substr(sTemp, length(rootId) + 4);
END;
//
SELECT * FROM t_tree WHERE FIND_IN_SET(id, `getChildrenBySingle`(2));
DROP FUNCTION IF EXISTS `getChildrenByMultiContainSelf`;
delimiter //
CREATE FUNCTION `getChildrenByMultiContainSelf`(rootIds VARCHAR(1024))
RETURNS varchar(1024)
BEGIN
DECLARE sTemp VARCHAR(1024);
DECLARE sTempChd VARCHAR(1024);
SET sTemp = '$';
SET sTempChd = rootIds;
WHILE sTempChd is not null DO
SET sTemp = concat(sTemp, ',', sTempChd);
SELECT group_concat(id) INTO sTempChd FROM t_tree where FIND_IN_SET(pid, sTempChd) > 0;
END WHILE;
RETURN sTemp;
END;
//
SELECT * FROM t_tree WHERE FIND_IN_SET(id, `getChildrenByMultiContainSelf`('2,6'));
DROP FUNCTION IF EXISTS `getChildrenByMulti`;
delimiter //
CREATE FUNCTION `getChildrenByMulti`(rootIds VARCHAR(1024))
RETURNS varchar(1024)
BEGIN
DECLARE sTemp VARCHAR(1024);
DECLARE sTempChd VARCHAR(1024);
SET sTemp = '$';
SET sTempChd = rootIds;
WHILE sTempChd is not null DO
SET sTemp = concat(sTemp, ',', sTempChd);
SELECT group_concat(id) INTO sTempChd FROM t_tree where FIND_IN_SET(pid, sTempChd) > 0;
END WHILE;
RETURN substr(sTemp, length(rootIds) + 4);
END;
//
SELECT * FROM t_tree WHERE FIND_IN_SET(id, `getChildrenByMulti`('2,6'));
DROP FUNCTION IF EXISTS `getParentBySingleContainSelf`;
delimiter //
CREATE FUNCTION `getParentBySingleContainSelf`(rootId INT)
RETURNS varchar(1024)
BEGIN
DECLARE sTemp VARCHAR(1024);
DECLARE sTempPar VARCHAR(1024);
SET sTemp = '$';
SET sTempPar = rootId;
WHILE sTempPar is not null DO
SET sTemp = concat(sTemp, ',', sTempPar);
SELECT group_concat(pid) INTO sTempPar FROM t_tree where pid <> id and FIND_IN_SET(id, sTempPar) > 0;
END WHILE;
RETURN sTemp;
END;
//
SELECT * FROM t_tree WHERE FIND_IN_SET(id, getParentBySingleContainSelf(2));
DROP FUNCTION IF EXISTS `getParentBySingle`;
delimiter //
CREATE FUNCTION `getParentBySingle`(rootId INT)
RETURNS varchar(1024)
BEGIN
DECLARE sTemp VARCHAR(1024);
DECLARE sTempPar VARCHAR(1024);
SET sTemp = '$';
SET sTempPar = rootId;
WHILE sTempPar is not null DO
SET sTemp = concat(sTemp, ',', sTempPar);
SELECT group_concat(pid) INTO sTempPar FROM t_tree where pid <> id and FIND_IN_SET(id, sTempPar) > 0;
END WHILE;
RETURN substr(sTemp, length(rootId) + 4);
END;
//
SELECT * FROM t_tree WHERE FIND_IN_SET(id, getParentBySingle(2));
DROP FUNCTION IF EXISTS `getParentByMultiContainSelf`;
delimiter //
CREATE FUNCTION `getParentByMultiContainSelf`(rootIds VARCHAR(1024))
RETURNS varchar(1024)
BEGIN
DECLARE sTemp VARCHAR(1024);
DECLARE sTempPar VARCHAR(1024);
SET sTemp = '$';
SET sTempPar = rootIds;
WHILE sTempPar is not null DO
SET sTemp = concat(sTemp, ',', sTempPar);
SELECT group_concat(pid) INTO sTempPar FROM t_tree where pid <> id and FIND_IN_SET(id, sTempPar) > 0;
END WHILE;
RETURN sTemp;
END;
//
SELECT * FROM t_tree WHERE FIND_IN_SET(id, getParentByMultiContainSelf('3,7'));
DROP FUNCTION IF EXISTS `getParentByMulti`;
delimiter //
CREATE FUNCTION `getParentByMulti`(rootIds VARCHAR(1024))
RETURNS varchar(1024)
BEGIN
DECLARE sTemp VARCHAR(1024);
DECLARE sTempPar VARCHAR(1024);
SET sTemp = '$';
SET sTempPar = rootIds;
WHILE sTempPar is not null DO
SET sTemp = concat(sTemp, ',', sTempPar);
SELECT group_concat(pid) INTO sTempPar FROM t_tree where pid <> id and FIND_IN_SET(id, sTempPar) > 0;
END WHILE;
RETURN substr(sTemp, length(rootIds) + 4);
END;
//
SELECT * FROM t_tree WHERE FIND_IN_SET(id, getParentByMulti('3,7'));
如果在执行创建函数的语句时报如下错误,可以尝试执行以下SQL解决
Error Code: 1418. This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you might want to use the less safe log_bin_trust_function_creators variable) 0.000 sec
show VARIABLES like "log_bin_trust_function_creators";
set global log_bin_trust_function_creators = 1;
mysql递归查询方法|mysql递归查询遇到的坑,教你们解决办法
Mysql中的递归层次查询(根据父节点查找所有的子节点和根据子节点查询所有的父节点)的两种运用