认识MySQL的recursive common table expression

在介绍recursive common table expression之前,我们先来认识一下什么是common table expression。

Common Table Expressions

MySQL :: MySQL 8.0 Reference Manual :: 13.2.15 WITH (Common Table Expressions)中,它对common table expression (CTE)的解释如下:

A common table expression (CTE) is a named temporary result set that exists within the scope of a single statement and that can be referred to later within that statement, possibly multiple times.

一个common table expression (CTE)是一个拥有名称的临时结果集,它存在于一条语句的范围之内,它之后能被那条语句引用。

我们先看一个例子:

WITH cte (col1, col2) AS
(
  SELECT 1, 2
)
SELECT col1, col2 FROM cte;

上面的例子中,你使用with子句定义了一个名叫cte的CTE,它拥有(col1, col2)两列,它只拥有(1, 2)这一行数据。之后的SELECT语句就能够使用这个CTE了。执行上述语句的结果如下:

+------+------+
| col1 | col2 |
+------+------+
|    1 |    2 |
+------+------+

Recursive Common Table Expressions

介绍完CTE后,我们来看看recursive CTE是怎样的。

recursive CTE的子查询包含两部分,通过UNION [ALL]或者UNION DISTINCT分割。就像下面一样:

SELECT ...      -- return initial row set
UNION ALL
SELECT ...      -- return additional row sets

第一个SELECT为CTE产生初始行集,并且不会引用CTE的名称。第二个SELECT产生额外的行集,并且通过在它的FROM子句中引用CTE的名称递归,当不再产生新的行时,递归中止。递归的每次迭代只操作上一次迭代所产生的行。

让我们来看一个例子来更好地理解。

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte WHERE n < 5
)
SELECT * FROM cte;

# 执行结果如下:

+------+
| n    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
+------+

我们来分析一下为什么会得到这样的结果。首先SELECT 1会产生初始化行集,此时,cte所代表的结果集只有一行数据。接下来会开始第二个SELECT的递归。第一次迭代会操作初始化行集(1)并产生(2),第二次迭代会第一次迭代产生的行集(2)并产生(3),一直这样下去,知道递归中止,也就是n不再小于5时。

这里其实只是简单的介绍了CTE和recursive CTE,想了解更多的话还是建议去查看官方文档

参考资料

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容