MySQL版本8.0.21-2

递归方式生成一个临时表tmp,且填充了10条数据

WITH recursive tmp ( a, b ) AS (SELECT1,'2022-01-01' UNION ALLSELECTROUND( RAND()* 10 ),b - INTERVAL ROUND( RAND() * 1000 ) DAY FROMTMP LIMIT 10 ) TABLE tmp;

以列a递增

WITH recursive tmp ( a, b ) AS (SELECT 1, '2022-01-01' UNION ALL SELECT a + 1, b - INTERVAL ROUND( RAND() * 1000 ) DAY FROM TMP LIMIT 10 ) TABLE tmp;

输出1~n:

WITH RECURSIVE cte (n) AS
(SELECT 1UNION ALLSELECT n + 1 FROM cte LIMIT 10
)
SELECT * FROM cte;
#可将`LIMIT`改成`WHERE n < 10`
+----+
| n  |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
|  6 |
|  7 |
|  8 |
|  9 |
| 10 |
+----+

输出n!,即n的阶乘:

WITH RECURSIVE cte ( n, m ) AS ( SELECT 1, 1 UNION ALL SELECT n + 1, ( n + 1 ) * m FROM cte WHERE n < 10 ) SELECT
*
FROMcte;
#或者
WITH RECURSIVE cte AS (SELECT1 AS n,1 AS m UNION ALLSELECTn + 1,( n + 1 ) * m FROMcte WHEREn < 10 ) SELECT*
FROMcte;
+----+---------+
| n  | m       |
+----+---------+
|  1 |       1 |
|  2 |       2 |
|  3 |       6 |
|  4 |      24 |
|  5 |     120 |
|  6 |     720 |
|  7 |    5040 |
|  8 |   40320 |
|  9 |  362880 |
| 10 | 3628800 |
+----+---------+

输出前n个数的和:

WITH RECURSIVE cte AS ( SELECT 1 AS n, 1 AS sum UNION ALL SELECT n + 1, sum + n + 1 FROM cte WHERE n < 10 ) SELECT
*
FROMcte;
+----+-----+
| n  | sum |
+----+-----+
|  1 |   1 |
|  2 |   3 |
|  3 |   6 |
|  4 |  10 |
|  5 |  15 |
|  6 |  21 |
|  7 |  28 |
|  8 |  36 |
|  9 |  45 |
| 10 |  55 |
+----+-----+

简单递归用法:
首先我们引出一个问题: 什么叫做递归?
递归:给定函数初始条件,然后反复调用自身直到终止条件.

例子1:递归得到依次递增的序列:

WITH RECURSIVE cte (n) AS
(SELECT 1UNION ALLSELECT n + 1 FROM cte WHERE n < 5
)
SELECT * FROM cte;
+---+
| n |
+---+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+---+

官方文档中对于这个写法的解释:

At each iteration, that SELECT produces a row with a new value one greater than the value of n from the previous row set. The first iteration operates on the initial row set (1) and produces 1+1=2; the second iteration operates on the first iteration’s row set (2) and produces 2+1=3; and so forth. This continues until recursion ends, which occurs when n is no longer less than 5.

也就是说,一个with recursive 由两部分组成。第一部分是非递归部分(union all上方),第二部分是递归部分(union all下方)。递归部分第一次进入的时候使用非递归部分传递过来的参数。也就是第一行的数据值,进而得到第二行数据值。然后根据第二行数据值得到第三行数据值。

例子2:递归得到不断复制的字符串
这里的as表示列名,表示说这个CTE有两个列,也可以写为with cte(n,str) as (subquery)

WITH RECURSIVE cte AS
(SELECT 1 AS n, 'abc' AS strUNION ALLSELECT n + 1, CONCAT(str, str) FROM cte WHERE n < 3
)
SELECT * FROM cte;

结果:

+---+-----+
| n | str |
+---+-----+
| 1 | abc |
| 2 | abc |
| 3 | abc |
+---+-----+

或者报错:‘Data too long for column ‘str’ at row 1’

这里的话concat是每一次都连接一个str,这个str来自上一行的结果,但是最终输出却是每一行都没有变化的值,这是为什么?
这是因为我们在声明str的时候限制了它的字符长度,使用 类型转换CAST('abc' AS CHAR(30)) 就可以得到复制的字符串了。
**注意:**这里也可能会报错,看mysql模式在严格模式下这里会显示Error Code: 1406. Data too long for column ‘str’ at row 1
关于strict SQL mode和nonstrict SQL mode:mysql 严格模式 Strict Mode说明

WITH RECURSIVE cte AS
(SELECT 1 AS n, CAST('abc' AS CHAR(20)) AS strUNION ALLSELECT n + 1, CONCAT(str, str) FROM cte WHERE n < 3
)
SELECT * FROM cte;
+---+--------------+
| n | str          |
+---+--------------+
| 1 | abc          |
| 2 | abcabc       |
| 3 | abcabcabcabc |
+---+--------------+

当然,如果上一行的值有多个,我们还可以对多个值进行重新组合得到我们想要的结果,比如下面这个例子。

例子3:生成斐波那契数列

WITH RECURSIVE fibonacci (n, fib_n, next_fib_n) AS
(SELECT 1, 0, 1UNION ALLSELECT n + 1, next_fib_n, fib_n + next_fib_nFROM fibonacci WHERE n < 92
)
SELECT * FROM fibonacci;
+----+---------------------+---------------------+
| n  | fib_n               | next_fib_n          |
+----+---------------------+---------------------+
|  1 |                   0 |                   1 |
|  2 |                   1 |                   1 |
|  3 |                   1 |                   2 |
|  4 |                   2 |                   3 |
|  5 |                   3 |                   5 |
|  6 |                   5 |                   8 |
|  7 |                   8 |                  13 |
|  8 |                  13 |                  21 |
|  9 |                  21 |                  34 |
| 10 |                  34 |                  55 |
| 11 |                  55 |                  89 |
| 12 |                  89 |                 144 |
| 13 |                 144 |                 233 |
| 14 |                 233 |                 377 |
| 15 |                 377 |                 610 |
| 16 |                 610 |                 987 |
| 17 |                 987 |                1597 |
| 18 |                1597 |                2584 |
| 19 |                2584 |                4181 |
| 20 |                4181 |                6765 |
| 21 |                6765 |               10946 |
| 22 |               10946 |               17711 |
| 23 |               17711 |               28657 |
| 24 |               28657 |               46368 |
| 25 |               46368 |               75025 |
| 26 |               75025 |              121393 |
| 27 |              121393 |              196418 |
| 28 |              196418 |              317811 |
| 29 |              317811 |              514229 |
| 30 |              514229 |              832040 |
| 31 |              832040 |             1346269 |
| 32 |             1346269 |             2178309 |
| 33 |             2178309 |             3524578 |
| 34 |             3524578 |             5702887 |
| 35 |             5702887 |             9227465 |
| 36 |             9227465 |            14930352 |
| 37 |            14930352 |            24157817 |
| 38 |            24157817 |            39088169 |
| 39 |            39088169 |            63245986 |
| 40 |            63245986 |           102334155 |
| 41 |           102334155 |           165580141 |
| 42 |           165580141 |           267914296 |
| 43 |           267914296 |           433494437 |
| 44 |           433494437 |           701408733 |
| 45 |           701408733 |          1134903170 |
| 46 |          1134903170 |          1836311903 |
| 47 |          1836311903 |          2971215073 |
| 48 |          2971215073 |          4807526976 |
| 49 |          4807526976 |          7778742049 |
| 50 |          7778742049 |         12586269025 |
| 51 |         12586269025 |         20365011074 |
| 52 |         20365011074 |         32951280099 |
| 53 |         32951280099 |         53316291173 |
| 54 |         53316291173 |         86267571272 |
| 55 |         86267571272 |        139583862445 |
| 56 |        139583862445 |        225851433717 |
| 57 |        225851433717 |        365435296162 |
| 58 |        365435296162 |        591286729879 |
| 59 |        591286729879 |        956722026041 |
| 60 |        956722026041 |       1548008755920 |
| 61 |       1548008755920 |       2504730781961 |
| 62 |       2504730781961 |       4052739537881 |
| 63 |       4052739537881 |       6557470319842 |
| 64 |       6557470319842 |      10610209857723 |
| 65 |      10610209857723 |      17167680177565 |
| 66 |      17167680177565 |      27777890035288 |
| 67 |      27777890035288 |      44945570212853 |
| 68 |      44945570212853 |      72723460248141 |
| 69 |      72723460248141 |     117669030460994 |
| 70 |     117669030460994 |     190392490709135 |
| 71 |     190392490709135 |     308061521170129 |
| 72 |     308061521170129 |     498454011879264 |
| 73 |     498454011879264 |     806515533049393 |
| 74 |     806515533049393 |    1304969544928657 |
| 75 |    1304969544928657 |    2111485077978050 |
| 76 |    2111485077978050 |    3416454622906707 |
| 77 |    3416454622906707 |    5527939700884757 |
| 78 |    5527939700884757 |    8944394323791464 |
| 79 |    8944394323791464 |   14472334024676221 |
| 80 |   14472334024676221 |   23416728348467685 |
| 81 |   23416728348467685 |   37889062373143906 |
| 82 |   37889062373143906 |   61305790721611591 |
| 83 |   61305790721611591 |   99194853094755497 |
| 84 |   99194853094755497 |  160500643816367088 |
| 85 |  160500643816367088 |  259695496911122585 |
| 86 |  259695496911122585 |  420196140727489673 |
| 87 |  420196140727489673 |  679891637638612258 |
| 88 |  679891637638612258 | 1100087778366101931 |
| 89 | 1100087778366101931 | 1779979416004714189 |
| 90 | 1779979416004714189 | 2880067194370816120 |
| 91 | 2880067194370816120 | 4660046610375530309 |
| 92 | 4660046610375530309 | 7540113804746346429 |
+----+---------------------+---------------------+
92 rows in set (0.06 sec)

试了下最多可以生成92位,93就报错BIGINT UNSIGNED value is out of range in ‘(fibonacci.num + fibonacci.next_num)’,测试MySQL版本为8.0.21

改成这样:

WITH recursive fibonacci AS (SELECT 1 AS n,0 AS num,CAST(1 AS UNSIGNED) AS next_numUNION ALLSELECT n + 1, next_num, num + next_num FROM fibonacci WHERE n < 93
) SELECT * FROM fibonacci;
+----+---------------------+----------------------+
| n  | num                 | next_num             |
+----+---------------------+----------------------+
|  1 |                   0 |                    1 |
|  2 |                   1 |                    1 |
|  3 |                   1 |                    2 |
|  4 |                   2 |                    3 |
|  5 |                   3 |                    5 |
|  6 |                   5 |                    8 |
|  7 |                   8 |                   13 |
|  8 |                  13 |                   21 |
|  9 |                  21 |                   34 |
| 10 |                  34 |                   55 |
| 11 |                  55 |                   89 |
| 12 |                  89 |                  144 |
| 13 |                 144 |                  233 |
| 14 |                 233 |                  377 |
| 15 |                 377 |                  610 |
| 16 |                 610 |                  987 |
| 17 |                 987 |                 1597 |
| 18 |                1597 |                 2584 |
| 19 |                2584 |                 4181 |
| 20 |                4181 |                 6765 |
| 21 |                6765 |                10946 |
| 22 |               10946 |                17711 |
| 23 |               17711 |                28657 |
| 24 |               28657 |                46368 |
| 25 |               46368 |                75025 |
| 26 |               75025 |               121393 |
| 27 |              121393 |               196418 |
| 28 |              196418 |               317811 |
| 29 |              317811 |               514229 |
| 30 |              514229 |               832040 |
| 31 |              832040 |              1346269 |
| 32 |             1346269 |              2178309 |
| 33 |             2178309 |              3524578 |
| 34 |             3524578 |              5702887 |
| 35 |             5702887 |              9227465 |
| 36 |             9227465 |             14930352 |
| 37 |            14930352 |             24157817 |
| 38 |            24157817 |             39088169 |
| 39 |            39088169 |             63245986 |
| 40 |            63245986 |            102334155 |
| 41 |           102334155 |            165580141 |
| 42 |           165580141 |            267914296 |
| 43 |           267914296 |            433494437 |
| 44 |           433494437 |            701408733 |
| 45 |           701408733 |           1134903170 |
| 46 |          1134903170 |           1836311903 |
| 47 |          1836311903 |           2971215073 |
| 48 |          2971215073 |           4807526976 |
| 49 |          4807526976 |           7778742049 |
| 50 |          7778742049 |          12586269025 |
| 51 |         12586269025 |          20365011074 |
| 52 |         20365011074 |          32951280099 |
| 53 |         32951280099 |          53316291173 |
| 54 |         53316291173 |          86267571272 |
| 55 |         86267571272 |         139583862445 |
| 56 |        139583862445 |         225851433717 |
| 57 |        225851433717 |         365435296162 |
| 58 |        365435296162 |         591286729879 |
| 59 |        591286729879 |         956722026041 |
| 60 |        956722026041 |        1548008755920 |
| 61 |       1548008755920 |        2504730781961 |
| 62 |       2504730781961 |        4052739537881 |
| 63 |       4052739537881 |        6557470319842 |
| 64 |       6557470319842 |       10610209857723 |
| 65 |      10610209857723 |       17167680177565 |
| 66 |      17167680177565 |       27777890035288 |
| 67 |      27777890035288 |       44945570212853 |
| 68 |      44945570212853 |       72723460248141 |
| 69 |      72723460248141 |      117669030460994 |
| 70 |     117669030460994 |      190392490709135 |
| 71 |     190392490709135 |      308061521170129 |
| 72 |     308061521170129 |      498454011879264 |
| 73 |     498454011879264 |      806515533049393 |
| 74 |     806515533049393 |     1304969544928657 |
| 75 |    1304969544928657 |     2111485077978050 |
| 76 |    2111485077978050 |     3416454622906707 |
| 77 |    3416454622906707 |     5527939700884757 |
| 78 |    5527939700884757 |     8944394323791464 |
| 79 |    8944394323791464 |    14472334024676221 |
| 80 |   14472334024676221 |    23416728348467685 |
| 81 |   23416728348467685 |    37889062373143906 |
| 82 |   37889062373143906 |    61305790721611591 |
| 83 |   61305790721611591 |    99194853094755497 |
| 84 |   99194853094755497 |   160500643816367088 |
| 85 |  160500643816367088 |   259695496911122585 |
| 86 |  259695496911122585 |   420196140727489673 |
| 87 |  420196140727489673 |   679891637638612258 |
| 88 |  679891637638612258 |  1100087778366101931 |
| 89 | 1100087778366101931 |  1779979416004714189 |
| 90 | 1779979416004714189 |  2880067194370816120 |
| 91 | 2880067194370816120 |  4660046610375530309 |
| 92 | 4660046610375530309 |  7540113804746346429 |
| 93 | 7540113804746346429 | 12200160415121876738 |
+----+---------------------+----------------------+
93 rows in set (0.10 sec)

可以生成到93个(长度20了),但是94+都不行了,达到了bigint上限

语法说明:
UNION ALLUNION DISTINCT

UNION ALL:非递归部分和递归部分用UNION ALL分隔,那么所有的行都会被加入到最后的表中
UNION DISTINCT:非递归部分和递归部分用UNION DISTINCT分隔,重复的行被消除。这对于执行传递闭包的查询非常有用,以避免无限循环。

limit控制递归次数

recursive(第二个select)不能使用的结构:

官网的描述:

The recursive SELECT part must not contain these constructs:(递归查询部分必须不含下列结构)

Aggregate functions such as SUM(),聚合函数例如SUM()
Window functions
GROUP BY
ORDER BY
DISTINCT

限制递归次数/时间:
当出现不符合设置情况的会报错,分为以下几种设置方法:

cte_max_recursion_depth :default 设置为1000,表达递归的层数.可以使用如下语句修改这个值:

SET SESSION cte_max_recursion_depth = 10;      -- permit only shallow recursion
SET SESSION cte_max_recursion_depth = 1000000; -- permit deeper recursion

当然也可以设置为global,也就是set global cte_max_recursion_depth = 1000000;这样子就对全局的递归都有限制

max_execution_time :设置最近的递归时间

SET max_execution_time = 1000; -- impose one second timeout

MAX_EXECUTION_TIME:设置全局的递归时间

官网文档说明如下:

The cte_max_recursion_depth system variable enforces a limit on the
number of recursion levels for CTEs. The server terminates execution
of any CTE that recurses more levels than the value of this variable.

The max_execution_time system variable enforces an execution timeout
for SELECT statements executed within the current session.

The MAX_EXECUTION_TIME optimizer hint enforces a per-query execution
timeout for the SELECT statement in which it appears.

limit:限之最大行的数量

WITH RECURSIVE cte (n) AS
(SELECT 1UNION ALLSELECT n + 1 FROM cte LIMIT 10000
)
SELECT * FROM cte;

报错Recursive query aborted after 1001 iterations. Try increasing @@cte_max_recursion_depth to a larger value.

MySql 实现递归with recursive相关推荐

  1. 递归神经网络(Recursive Neural Network, RNN)

    信息往往还存在着诸如树结构.图结构等更复杂的结构.这就需要用到递归神经网络 (Recursive Neural Network, RNN),巧合的是递归神经网络的缩写和循环神经网络一样,也是RNN,递 ...

  2. RLS递归最小二乘法(Recursive Least Squares)

    RLS递归最小二乘法(Recursive Least Squares) 感谢B站Up 凩子白的讲解视频, 大多数的RLS算法介绍都是从各种专业领域角度讲解的(比如滤波器等角度), 对于缺乏专业背景的同 ...

  3. 深度学习——结构递归神经网络(Recursive NN)

    深度学习--结构递归神经网络(Recursive NN) 1.递归神经网络介绍 目前,递归神经网络一共包含两种,一种是时间递归神经网络(Recurrent NN),另外一种是结构性递归神经网络(Rec ...

  4. mysql之递归树查询

    mysql之递归树查询   写在前面   最近一段时间做的产品使用到了mysql数据库,虽然之前也使用过,但都是在业余时间使用,真正在项目中使用还是发现mysql的一些不同之处,比如函数.存储过程等, ...

  5. mysql+mybatis递归调用

    递归调用的应用场景常常出现在多级嵌套的情况,比如树形的菜单.下面通过一个简单的例子来实现mysql+mybatis的递归. 数据模型 private Integer categoryId;privat ...

  6. mysql cte递归_CTE 递归查询全解

    TSQL脚本能实现递归查询,用户使用共用表表达式 CTE(Common Table Expression),只需要编写少量的代码,就能实现递归查询.本文详细介绍CTE递归调用的特性和使用示例,递归查询 ...

  7. 有趣的递归缩写(Recursive acronym)

    看到一些递归缩写,很想知道到底有多少缩写是这样的,于是Google了一下,知道了英文说法是Recursive acronym,从 Wikipedia上摘录了一些: 递归缩写是一种在全称中递归引用它自身 ...

  8. 递归数列(recursive sequence)

    递归数列-递归数列 (recursive sequence ):一种用归纳方法给定的数列. 递归数列-举例 例如,等比数列可以用归纳方法来定义,先定义第一项 a1 的值( a1 ≠ 0 ),对 于以后 ...

  9. Oracle转换MySql之递归start with

    Oracle转换Mysql之start with: oracle转mysql其实很多细节,这边就不一 一 描述了,这边先整理些"坎"吧! Oracle中start with - : ...

最新文章

  1. My blog please navigate to http://hi.baidu.com/248828412
  2. linux自己带的apache重新启动
  3. linux alpine 用dockerfile创建的ssh镜像
  4. Android群英传笔记——第四章:ListView使用技巧
  5. java 可用内存_总可用内存java
  6. 【数据结构与算法-2】链表
  7. springboot web 服务器选择
  8. python matplotlib画图产生的Type 3 fonts字体没有嵌入问题
  9. rxjs的pipe和map配合使用的单步调试
  10. SSH连接linux时,长时间不操作就断开的解决方案
  11. python class def 格式_Python symbol.classdef方法代码示例
  12. windows下安装Redis数据库
  13. 如何使用XGBoost开发随机森林集成
  14. 03.subview_and_superview
  15. Brocade 6510 交换机清空配置,重新initiator交换机
  16. VC所有版本一键清除缓存垃圾脚本
  17. oracle12c 删除磁盘组,12C RAC重装无法识别磁盘组(AFD新特性)
  18. AFM成像表面形貌和表面粗糙度
  19. HDFS Router-based Federation
  20. 神经网络解决推荐系统问题(NCF)

热门文章

  1. Solr查询参数说明
  2. ipone低版本页面不渲染问题
  3. 安装篇——用halyard安装Spinnaker
  4. SQL中如何取前百分之N的记录?
  5. 百分位数的计算原理--NumPy数组实现
  6. Activiti/Flowable/Camunda介绍
  7. 施努卡:机器人视觉案例(工业机器人的案例)
  8. imac 使用 linux终端,MAC 终端(命令行)剪切版的使用
  9. React_Fragments
  10. 视频教程-Docker虚拟化容器-区块链