sqlite3不支持递归聚合查询的替代方法

时间:2019-03-26 03:24:06

标签: recursion sqlite aggregate-functions

我想对随时间变化的系统执行SQL计算

v <- v + a (*) v

其中vN个分量(N >> 10)的向量,aNN的矩阵稀疏,(*)表示矩阵乘法,并且演化是作为时间步长序列递归计算的,每个步长都使用v的先前值。 a随时间变化是一个外部因素,但是假设a是恒定的,对于这个问题就足够了。

我可以用命令式语言执行此递归循环,但是基础数据有点混乱,SQL对于规范化非常出色。仅用一种语言完成工作会很整齐。

我发现矩阵乘法很好。从sqlite 3.8开始,递归也很好。但是递归循环中的矩阵乘法似乎是不可能的。这是我到目前为止的进度(也在http://sqlfiddle.com/#!5/ed521/1):

-- Example vector v
DROP TABLE IF EXISTS coords;
CREATE TABLE coords( row INTEGER PRIMARY KEY, val FLOAT );
INSERT INTO coords
VALUES
(1, 0.0 ),
(2, 1.0 );

-- Example matrix a
DROP TABLE IF EXISTS matrix;
CREATE TABLE matrix( row INTEGER, col INTEGER, val FLOAT, PRIMARY KEY( row, col ) );
INSERT INTO matrix
VALUES
( 1, 1, 0.0 ),
( 1, 2, 0.03 ),
( 2, 1, -0.03 ),
( 2, 2, 0.0 );

-- The timestep equation can also be expressed: v <- ( I + a ) (*) v, where the                
-- identity matrix I is first added to a.                                                      
UPDATE matrix
SET val = val + 1.0
WHERE row == col;

-- Matrix multiply to evaluate the first step.                                                 
SELECT a.row AS row, SUM( a.val*v.val ) AS val
FROM coords v
JOIN matrix a
ON a.col == v.row
GROUP BY a.row;

在这里出现问题。我看不到没有矩阵怎么做矩阵乘法 GROUP BY(聚合)操作,但是Sqlite3专门不允许在递归循环内进行聚合:

-- Recursive matrix multiply to evaluate a sequences of steps.                                 
WITH RECURSIVE trajectory( row, val ) AS
(
        SELECT row, val
        FROM coords

        UNION ALL

        SELECT a.row AS row, SUM( a.val*v.val ) AS val
        FROM trajectory v       -- recursive sequence of steps                               
        --FROM coords v           -- non-recursive first step only                               
        JOIN matrix a
        ON a.col == v.row
        GROUP BY a.row
        LIMIT 50
)
SELECT *
FROM trajectory;

返回

Error: recursive aggregate queries not supported

毫无疑问,设计师有明确的理由将其排除在外!我很惊讶JOIN被允许,但是GROUP BY被禁止。不过,我不确定我有什么选择。

我还找到了其他一些递归示例,但是它们似乎都经过了精心选择的问题,对于这些问题,不需要在循环内进行聚合或自联接。在docs(https://www.sqlite.org/lang_with.html)中,示例查询以递归方式遍历树,并对输出执行avg()。这有一点不同:聚合发生在循环外部,树遍历使用JOIN,但递归循环内部没有聚合。仅仅因为递归不依赖于聚合,才出现该问题,就像在此问题中一样。

另一个例子,斐波那契发生器是N = 2线性动力系统的一个例子,但是使用N = 2,实现可以硬编码这两个值,矩阵直接乘到查询中,所以无需汇总SUM()。一般来说,N >> 10沿着这条路走是不可行的。

任何帮助将不胜感激。谢谢!

0 个答案:

没有答案