MySQL递归查询(with recursive)

发布于:2024-06-26 ⋅ 阅读:(34) ⋅ 点赞:(0)

背景

日常开发中经常会有那种 阶梯式 数据,比如做地图、菜单,裂变给上级、上上级分红等等这样的需求的时候

你需要找个一个对象的 上级,上上级,上上上级

在这里插入图片描述
建了一张很容易理解阶级的表,一目了然
很多时候我们的需求就是,通过任何一个人的id,找到它所有的上级,比如我们想通过儿子的id,找他的"族谱"

我们的确是可以用 递归 的思想去做这个事,用代码可以轻易地实现。与此同时我们也会发现,连接数据库的次数,也和我们递归的次数相同,这还是耗费资源的

还有没有其它的方法呢?这也是曾经一个面试官问我的问题,现在想来,当时的确没回答好,今天它来了

with recursive

它是什么?

MySQL with Recursive是一种基于递归思想的MySQL查询方式,可以实现对数据的递归查询和处理,返回符合条件的数据。在MySQL 8.0版本中,该功能被正式引入。

语法:

WITH RECURSIVE temp(column_list) AS (
    SELECT query_list
    UNION [ALL]
    SELECT query_list
    FROM table_name
    WHERE condition
)
SELECT * FROM temp

解释:
WITH RECURSIVE:

表示要使用递归查询的方式处理数据

temp:

给这个临时的递归表取个名字,可以在初始查询和递归查询中引用

column_list:

表示 temp 查询表中包含的列名,列名之间用逗号分隔

UNION ALL

将两个查询结果集进行联合

以上面那张表为例,我想找到儿子的 “族谱”

WITH recursive temp AS (
SELECT
	id,
	`name`,
	parent_id 
FROM
	person 
WHERE
	id = 3 UNION ALL
SELECT
  p.id,
	p.`name`,
	p.parent_id 
FROM
	person p,
	temp 
WHERE
	p.id = temp.parent_id 
	) SELECT
	* 
FROM
	temp

我们把儿子的 id 作为条件,查询来的结果作为递归的条件,去从它自身开始,递归 向上 找它的 父亲,以及父亲的父亲。这就是这句 SQL的翻译
在这里插入图片描述
这是我们想要的结果:

如果想通过 “顶级父类”,查看它下面的 子集也可以,我们稍微改动一下我们SQL

WITH recursive temp AS (
SELECT
	id,
	`name`,
	parent_id 
FROM
	person 
WHERE
	id = 1 UNION ALL
SELECT
	p.id,
	p.`name`,
	p.parent_id 
FROM
	person p,
	temp 
WHERE
	p.parent_id = temp.id 
	) SELECT
	* 
FROM
	temp

在这里插入图片描述
思考第一个问题:就是我们每次查询这个链条的时候只能是保证单边查询,要是能向两边延展查询就好了,比如我们输入 父亲的id,最终的结果是:父亲、儿子、爷爷、都能找到


网站公告

今日签到

点亮在社区的每一天
去签到