Mysql 8+支持递归查询 recursive关键字

背景

递归查询表中下级/上级数据(可指定递归多少层)
本文参照实现Oracle的递归 start with … connect by … prior。
当然,recursive关键字自由度很高,可以自行考虑实现怎样的功能,阶乘等等基于递归都可以。
注意存在递归最大层数1000的限制

ps:关键字没用大写

表中数据

在这里插入图片描述

栗子

先说下语法吧,不然可能要瞪眼理解一会。

一.with … as (…)语法 ,当然可以直接跳过不看这里

ps:with as语法视为创建一个临时表(8+版本支持),供其他sql使用,例如:

with
temp1 as (
    select 1 as id,  '张三' as name
   union all 
    select 2 as id, '李四' as name),
temp2 as (select 1 as id)
select temp1.id, temp1.name
  from temp1
  join temp2 on temp1.id = temp2.id;

ps:写栗子的时候想着下面这样子实现

with temp as(...), 
recursive re_temp() as(...)
 select ...from temp...

结果发现会报语法错误,不知是我格式不正确还是目前不支持,欢迎指点。

二.进入正题 with recursive temp(…) as(…)

1.基本实现

-- temp自定义临时表名, (id, name)表示查询哪些字段,按需定义,不必须与下面查询一致,规范起见建议保持一致
with recursive temp(id, `name`) as (
    -- 递归所用的基础数据,对照oracle就是start with...
	select id, `name`
	  from source
	 where id = 1
 union all
    -- 递归关联查询语句,对照oracle就是connect by ... prior ...
    -- 这里就可以根据关联条件来定义是向上还是向下递归咯
	select s.id, s.`name`
	  from source s, temp
	 where s.pid = temp.id
)
select id, `name` from temp;

查询结果:
在这里插入图片描述

以上是基本使用。
参照Oracle,每一层递归记录对应一个level,并可以基于level控制递归层数,这里mysql实现如下:

2.+level实现

with recursive temp(id, `name`, `level`) as (
	select id, `name`, 1 
	  from source
	 where id = 1
 union all
	select s.id, s.`name`, temp.`level`+1
	  from source s, temp
	 where s.pid = temp.id
)
select id, `name`, `level` from temp;

在这里插入图片描述

3.+level实现递归层数控制

with recursive temp(id, `name`, `level`) as (
	select id, `name`, 1 
	  from source
	 where id = 1
 union all
	select s.id, s.`name`, temp.`level`+1
	  from source s, temp
	 where s.pid = temp.id
	   -- 控制递归层数
	   and `level` < 3
)
select id, `name, `level` from temp;

在这里插入图片描述

之前写过基于存储过程和group_concat的mysql递归

基于存储过程和group_concat的mysql比较烦

我之前遇到的坑:

  • 子查询调用存储过程需要find_in_set;
  • 长度过长需要设置会话级别的group_concat最大长度(group_concat_max_len),强烈不建议直接设置全局变量,有啥想法去找DBA聊聊吧。什么?没有DBA?你就可以为所欲为了?

本文就到这里吧,其他recursive递归编程自行百度。

~~放下手机,关上电脑
~~多做点有意义的事
~~避开疫情,三三两两出去看看风景不香吗
~~带上老婆出去拍个照,白首回望当下的心境不香吗
~~抓起娃娃出去带他长长见识,陪伴孩子点滴成长不香吗
~~读书不要停,学不进去技术就培养下其他感兴趣的书,读书不必有目的。打游戏50年你能得到啥?读书1年你能得到啥?期待你读除了技术外的书,期待你感谢自己。

希望你搜索mysql 递归查询不是上级让你做的~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值