Mysql中的递归查询

需求

按条件查询菜单及其子菜单。

表结构

sys_menu表,一列是id,一列是parent_idlevel表示菜单层级,name菜单名称。

其中level=1的跟菜单,parent_id为空。

查询语句

SELECT @pid,menu.* FROM (select * from sys_menu order by level) menu,(SELECT @pid := '$') pd
where ((FIND_IN_SET( menu.parent_id, @pid ) > 0) or 
	(menu.parent_id is null and menu.level=1 and menu.name!='需要过滤的根菜单条件'))
AND ((@pid := concat( @pid, ',', menu.id )) is not null)

说明

利用@pid临时参数,每次匹配到一个符合条件的,则将id加入@pid变量中。
过滤时,利用FIND_IN_SET@pid中查找parent_id在其中的菜单。

其中跟菜单利用的是另外的逻辑(例子里是排除了指定名称的跟菜单)。

陷阱

其实这应该不算一个官方方案,在Mysql5.7可以,如果在Mysql 8中,最好还是利用CTE实现。

注意到第一个子查询有order by level,这样确保了根节点会被首先加入@pid中,否则当全表查询时,可能子节点会先被找到而漏掉。

原文地址:https://www.cnblogs.com/mosakashaka/p/12794836.html