![6b7a84d5a8fb9f17c95b7752e80d812d.png](https://i-blog.csdnimg.cn/blog_migrate/8ea837d01f7940496dd7791702541f5a.jpeg)
你没看错标题,在这篇文章我将会给大家介绍使用 SQL 生成斐波那契数列,并且不需要借助任何物理表。
先来看什么是“斐波那契数列”?
下面是我从百度百科看到的定义:
斐波那契数列指的是这样一个数列: 1,1,2,3,5,8,13,21,34,55,89...这个数列从第3项开始,每一项都等于前两项之和。
它的递推公式:
![6e32767c2694ab40491b68a75e4cf874.png](https://i-blog.csdnimg.cn/blog_migrate/c35f14799163be57f6455118f7689907.jpeg)
也就是说,知道了第一项和第二项的值,就可以递推出后面的所有项。
那怎么用 SQL 实现呢?我们先来看怎么做到不通过物理表就能生成连续的数值。在 Oracle 里面,可以使用 CONNECT BY
查询,但是在 MySQL 里面可没有这个函数。如果在 MySQL 8.0 之前,确实没有什么好的办法解决这个问题,在 MySQL 8.0 后,可以使用 CTE 递归来生成连续的数值。
如果我们要生成 1,2,3...10 的连续数值,可以这么写:
WITH recursive cte (id) AS
(SELECT
1 AS id
UNION
ALL
SELECT
id + 1
FROM
cte
WHERE id < 10)
SELECT
*
FROM
cte ;
解决了生成连续数值的问题,再来看看怎么生成斐波那契数列。
在 SQL 里面,从当前行去读取前两行的数据不容易实现,但只读前一行就容易很多。因此,我们在数据集中增加一列,用于存储上一行的斐波那契数。
Talk is cheap. Show me the code.
WITH recursive cte (id, curr, pre) AS
(SELECT
1 AS id,
1 AS curr,
1 AS pre
UNION
ALL
SELECT
id + 1,
IF(id < 2, 1, curr + pre),
curr
FROM
cte
WHERE id < 10)
SELECT
id AS n,curr AS f
FROM
cte ;
输出结果打印如下:
n f
--- ---
1 1
2 1
3 2
4 3
5 5
6 8
7 13
8 21
9 34
10 55
CTE 递归的语法在这里暂时不展开讲了,后面我会写一篇文章专门讲怎么理解 CTE 递归。
这个实现需要注意两点:
- 把需要取第 n - 2 行的数放到第 n - 1 行的另一个列里;
- 判断条件是
id < 2
而不是id <= 2
,因为 id = n - 1 。
来源:SQL实现
作者:zero
原文:SQL 生成斐波那契数列