需求
按条件查询菜单及其子菜单。
表结构
sys_menu
表,一列是id
,一列是parent_id
,level
表示菜单层级,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
中,否则当全表查询时,可能子节点会先被找到而漏掉。