MySQL递归公用表表达式

😇作者介绍:一个有梦想、有理想、有目标的,且渴望能够学有所成的追梦人。

🎆学习格言:不读书的人,思想就会停止。——狄德罗

⛪️个人主页:进入博主主页

🗼专栏系列:MySQL知识

🌼欢迎小伙伴们访问到博主的文章内容,在浏览阅读过程发现需要纠正的地方,烦请指出,愿能与诸君一同成长!

目录

文章内容如下

✏️前言

✏️一、添加菜单表

✏️二、递归公用表表达式

✏️三、测试运行结果

✏️总结


文章内容如下


✏️前言

MySQL递归公用表表达式,简称(CTE)递归CTE是一种特殊的CTE,它可以用来执行递归查询询,即查询可以自顶向下或自底向上遍历层级结构。在一些特殊情况下,我们会常用到这个方法去处理一些特殊情况。下面就用菜单表的信息来演示‘自顶向下遍历层级


✏️一、添加菜单表

👉在这之前我们先添加一张菜单表,方便后面测试,这里的菜单表仅仅提供参考,注意表的列名命名不算规范。运用到实际项目中的时候,要注意表列名的命名必须要规范哈。下面内容参考即可。代码如下

-- 菜单表
CREATE TABLE menu_table
(
	menu_id int PRIMARY KEY AUTO_INCREMENT NOT NULL , -- 主键自增
	menu_order varchar(500) NULL , -- 层级ID
	menu_icon varchar(20) NULL , -- 菜单图标
	menu_name varchar(20) NULL , -- 菜单名称
	menu_parent varchar(20) NULL , -- 父菜单名称
	menu_url varchar(100) NULL , -- 菜单url
	menu_permissionmark varchar(50) NULL , -- 权限标识
	menu_addtime datetime DEFAULT current_timestamp  NULL , -- 菜单创建时间
	menu_level varchar(500) NULL , -- 菜单层级关联id(父级为0)
	menu_state int NULL DEFAULT 1  -- 菜单状态

)COMMENT '菜单表',ENGINE = INNODB DEFAULT CHARSET=utf8 ;	select * from menu_table ;
-- 添加数据
INSERT INTO menu_table(menu_order,menu_icon,menu_name,menu_parent,menu_url,menu_permissionmark,menu_level)
VALUES 
('1','layui-icon-heart','系统管理','父级','indexs1.html','process.manage.list',null),
('2','layui-icon-heart','安全设置管理','父级','indexs2.html','role.manage.list',null),
('3','layui-icon-heart','工作流程','父级','indexs1.html','process.manage.list',null),
('4','layui-icon-heart','人力资源管理','父级','indexs2.html','role.manage.list',null),
('5','layui-icon-heart','企业信息管理','父级','indexs1.html','process.manage.list',null),
('6','layui-icon-heart','通讯管理','父级','indexs2.html','role.manage.list',null),
('7','layui-icon-heart','工作管理','父级','indexs1.html','process.manage.list',null),
('8','layui-icon-heart','时间管理','父级','indexs2.html','role.manage.list',null),
('9','layui-icon-heart','办公管理','父级','indexs1.html','process.manage.list',null),
('10','layui-icon-heart','组织架构管理','父级','indexs2.html','role.manage.list',null),

('11','layui-icon-heart','用户管理','1子级','indexs1.html','process.manage.list','1'),
('12','layui-icon-heart','角色管理','1子级','indexs2.html','role.manage.list','1'),
('13','layui-icon-heart','权限管理','1子级','indexs1.html','process.manage.list','2'),
('14','layui-icon-heart','流程管理','1子级','indexs2.html','role.manage.list','3'),
('15','layui-icon-heart','考勤管理','1子级','indexs1.html','process.manage.list','4'),
('16','layui-icon-heart','公告管理','1子级','indexs2.html','role.manage.list','5'),
('17','layui-icon-heart','邮件管理','1子级','indexs1.html','process.manage.list','6'),
('18','layui-icon-heart','任务管理','1子级','indexs2.html','role.manage.list','7'),
('19','layui-icon-heart','日程管理','1子级','indexs1.html','process.manage.list','8'),
('20','layui-icon-heart','计划管理','1子级','indexs2.html','role.manage.list','9'),
('21','layui-icon-heart','文件管理','1子级','indexs1.html','process.manage.list','1'),
('22','layui-icon-heart','笔记管理','1子级','indexs2.html','role.manage.list','1'),
('23','layui-icon-heart','员工通讯管理','1子级','indexs1.html','process.manage.list','6'),
('24','layui-icon-heart','讨论管理','1子级','indexs2.html','role.manage.list','6'),
('25','layui-icon-heart','便签管理','1子级','indexs1.html','process.manage.list','1'),
('26','layui-icon-heart','部门管理','1子级','indexs2.html','role.manage.list','10'),
('27','layui-icon-heart','采购部','2子级','indexs2.html','role.manage.list','26'),
('28','layui-icon-heart','外出岗','3子级','indexs2.html','role.manage.list','27'),
('29','layui-icon-heart','出口进货岗','3子级','indexs2.html','role.manage.list','27'),
('30','layui-icon-heart','财务部','2子级','indexs2.html','role.manage.list','26'),
('31','layui-icon-heart','会计师岗位','3子级','indexs2.html','role.manage.list','30'),
('32','layui-icon-heart','收银员岗位','3子级','indexs2.html','role.manage.list','30'),
('33','layui-icon-heart','菜单管理','1子级','indexs2.html','role.manage.list','1'),
('34','layui-icon-heart','市场部','2子级','indexs2.html','role.manage.list','26'),
('35','layui-icon-heart','总经办','2子级','indexs2.html','role.manage.list','26')

✏️二、递归公用表表达式

👉通过这个表达式,根据菜单名称查询到与这个名称相关的所有菜单信息,比如:‘部门管理’,在部门管理下有‘财务部’,在财务部下有‘会记岗’等等,使用这个表达式完成这一效果。

代码如下

WITH RECURSIVE SubMenu AS (
  SELECT
    a.menu_id,
    a.menu_name,
    a.menu_order,
    a.menu_level
  FROM
    menu_table AS a
  WHERE
    a.menu_name = '部门管理'
  UNION ALL
  SELECT
    b.menu_id,
    b.menu_name,
    b.menu_order,
    b.menu_level
  FROM
    menu_table AS b
  INNER JOIN SubMenu sm ON b.menu_level = sm.menu_order
)
SELECT * FROM SubMenu;

WITH RECURSIVE SubMenu AS (...)定义了一个递归CTE,它首先选择所有menu_name为“部门管理”的条目,然后递归地选择每一个条目下的子条目。UNION ALL用来合并每次递归查询的结果。

✏️三、测试运行结果


✏️总结

在这种查询中,每一次递归调用都会基于前一次查询的结果集,直到达到某个终止条件(例如,没有更多的子条目)。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
以下是使用Golang GORM进行MySQL递归查询单的示例代码: ```go package main import ( "fmt" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) type Category struct { ID int Name string ParentID int Children []Category `gorm:"foreignkey:ParentID"` } func main() { db, err := gorm.Open("mysql", "user:password@tcp(127.0.0.1:3306)/database?charset=utf8mb4&parseTime=True&loc=Local") if err != nil { panic(err) } defer db.Close() var categories []Category db.Where("parent_id = ?", 0).Preload("Children").Find(&categories) for _, category := range categories { fmt.Println(category.Name) for _, child := range category.Children { fmt.Println(" ", child.Name) } } } ``` 在这个示例中,我们定义了一个Category结构体,其中包含ID、Name、ParentID和Children字段。Children字段是一个Category类型的切片,用于存储子类别。在结构体中,我们使用了GORM的foreignkey标记来指定ParentID字段是外键,Children字段是通过ParentID字段与Category关联的。 在main函数中,我们首先使用GORM的Open函数打开MySQL数据库连接。然后,我们定义了一个categories切片,用于存储查询结果。我们使用GORM的Where函数指定ParentID为0,即查询所有顶级类别。然后,我们使用GORM的Preload函数预加载Children字段,以便在查询结果中包含子类别。最后,我们使用GORM的Find函数执行查询,并将结果存储在categories切片中。 最后,我们遍历categories切片,并打印每个类别及其子类别的名称。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半杯可可

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值