mysql递归查询语句

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql递归查询语句相关的知识,希望对你有一定的参考价值。

参考技术A mysql递归查询,mysql中从子类ID查询所有父类(做无限分类经常用到)

由于mysql 不支持类似 oracle with ...connect的 递归查询语法
之前一直以为类似的查询要么用存储过程要么只能用程序写递归查询.

现在发现原来一条sql语句也是可以搞定的

先来看数据表的结构如下:

id name parent_id
---------------------------
1 Home 0
2 About 1
3 Contact 1
4 Legal 2
5 Privacy 4
6 Products 1
7 Support 1
我要的要求是根据一个分类ID(这个分类ID可能是一个子分类),得到所有的父分类,下面是相应的SQL:

SELECT T2.id, T2.name
FROM (
SELECT
@r AS _id,
(SELECT @r := parent_id FROM table1 WHERE id = _id) AS parent_id,
@l := @l + 1 AS lvl
FROM
(SELECT @r := 5, @l := 0) vars,
table1 h
WHERE @r <> 0) T1
JOIN table1 T2
ON T1._id = T2.id
ORDER BY T1.lvl DESC

代码@r := 5标示查询id为5的所有父类。结果如下
1, ‘Home’
2, ‘About’
4, ‘Legal’
5, ‘Privacy’

自己仿照这看一下!

mysql树形结构递归查询

之前一直用的是Oracle,对于树形查询可以使用start with ... connect by 

select * from menu start with id=\'130000\' connect by id = prior parent_id;

 没错,这是Oracle所支持的

现在公司用的是mysql,对于这种查询方式只能通过sql语句实现了

语言都是相通的,何况sql呢

mysql随没有自带的语法支持,不过可以通过创建函数来实现递归查询。

 

 如下图所示。。。

 

直接上sql语句

create table `nodelist` (
    `id` int (11),
    `nodecontent` varchar (300),
    `pid` int (11)
); 
insert into `nodelist` (`id`, `nodecontent`, `pid`) values(\'1\',\'a\',NULL);
insert into `nodelist` (`id`, `nodecontent`, `pid`) values(\'2\',\'b\',\'1\');
insert into `nodelist` (`id`, `nodecontent`, `pid`) values(\'3\',\'c\',\'1\');
insert into `nodelist` (`id`, `nodecontent`, `pid`) values(\'4\',\'d\',\'2\');
insert into `nodelist` (`id`, `nodecontent`, `pid`) values(\'5\',\'e\',\'3\');
insert into `nodelist` (`id`, `nodecontent`, `pid`) values(\'6\',\'f\',\'3\');
insert into `nodelist` (`id`, `nodecontent`, `pid`) values(\'7\',\'g\',\'5\');
insert into `nodelist` (`id`, `nodecontent`, `pid`) values(\'8\',\'h\',\'7\');
insert into `nodelist` (`id`, `nodecontent`, `pid`) values(\'9\',\'i\',\'8\');
insert into `nodelist` (`id`, `nodecontent`, `pid`) values(\'10\',\'j\',\'8\');

 

 之后创建一个函数

DROP FUNCTION IF EXISTS `getChild`$$
CREATE DEFINER=`root`@`localhost` FUNCTION `getChild`(rootId INT) RETURNS VARCHAR(1000) CHARSET utf8
BEGIN
        DECLARE ptemp VARCHAR(1000);
        DECLARE ctemp VARCHAR(1000);
               SET ptemp = \'#\';
               SET ctemp =CAST(rootId AS CHAR);
               WHILE ctemp IS NOT NULL DO
                 SET ptemp = CONCAT(ptemp,\',\',ctemp);
                SELECT GROUP_CONCAT(id) INTO ctemp FROM nodelist   
                WHERE FIND_IN_SET(pid,ctemp)>0; 
               END WHILE;  
               RETURN ptemp;  
    END$$
DELIMITER ;

OK,查询可以通过将函数当做一个查询条件。

SELECT * FROM nodelist WHERE FIND_IN_SET(id, getChild(3))

 

上面难度相对比较大,再补充一个简单的自连接查询

SELECT t1.id,t1.nodecontent,t2.nodecontent parentnodecontent FROM nodelist t1
LEFT JOIN nodelist t2
ON t1.pid = t2.id

可以了。

借鉴 https://www.jianshu.com/p/f99665266bb1

里面用到的内置函数 https://baijiahao.baidu.com/s?id=1595349117525189591&wfr=spider&for=pc

你只要能想到的,都有对应的解决方式,幸运的是你该踩得一些坑别人实现给你填好了。

以上是关于mysql递归查询语句的主要内容,如果未能解决你的问题,请参考以下文章

mysql递归查询

递归SQL语句

mysql 递归查询sql语句的实现

SQL递归查询知多少

sql 怎么递归查询的方法:

ms sql 2005 递归查询如何实现