我在表中有一些初始行。我想用递归调用修改它们。在我的示例代码中,这个函数是2的简单乘法,我想执行5次:
WITH RECURSIVE cte (n,v) AS
(
-- initial values
SELECT 0,2
UNION ALL
SELECT 0,3
UNION ALL
-- generator
SELECT n + 1, v * 2 FROM cte WHERE n < 5
)
SELECT v FROM cte where n = 5;
它可以工作,但我的问题是它只过滤掉查询末尾不需要的值。如果我从更多的行开始,它会降低性能,因为我在内存中有更多的行。是否可以只在每次迭代中保留最新的值?
sqlfiddle:http://sqlfiddle.com/#!5/9eecb7/6761号
2条答案
按热度按时间kgqe7b3p1#
在sqlite中可以使用offset子句
offset子句(如果存在并且具有正值n)将阻止前n行添加到递归表中。前n行仍然由递归select处理—它们只是没有添加到递归表中。在跳过所有偏移行之前,不会对满足限制的行进行计数。
演示:http://sqlfiddle.com/#!5/9eecb7/6804号
在上述示例中,偏移量的计算方式为初始选择中的初始行数(2行)乘以迭代次数(5)=>2*5=10
顺便说一下,在这个具体的例子中,更好的解决方案是计算简单
X * 2^5
(x乘以2到5的幂)而不是递归。kknvjkwl2#
在sqlite中,cte被实现为一个协程(如explain输出所示),因此只有当前行保留在内存中,并且性能不会因为内存使用而降低。
mysql不允许在递归选择部分进行限制。如果我正确解释了wl#3634,那么8.0版中的实现总是完全实现递归CTE。
所以在sqlite中,您不需要做任何事情,而在mysql中,您不能做任何事情。