SQLite递归函数

p4rjhz4m  于 2022-11-14  发布在  SQLite
关注(0)|答案(1)|浏览(191)

我在SQLite中有一个视图,其中两列需要遵循递归公式。输入数据示例如下:
Date|Ca|Cb|CC
-|-|
2020-01-01|空|空|100.0
2020-01-02|0.1|空|空
2020-01-03|0.2|空|空
2020-01-04|0.1|空|空
2020-01-05|0.4|空|空
2020-01-06|0.3|空|空
2020-01-07|0.2|空|空
2020-01-08|0.4|空|空

CREATE TABLE "Test" (
    "Date"  DATE,
    "Ca"    NUMERIC,
    "Cb"    NUMERIC,
    "Cc"    NUMERIC
);

INSERT INTO Test (Date, Ca, Cb, Cc)
VALUES ( '2020-01-01',  NULL, NULL, 100.0),
( '2020-01-02', 0.1, NULL, NULL),
( '2020-01-03', 0.2 , NULL, NULL),
( '2020-01-04', 0.1 ,  NULL, NULL),
( '2020-01-05', 0.4 , NULL, NULL),
( '2020-01-06', 0.3 , NULL, NULL),
( '2020-01-07', 0.2 , NULL, NULL),
( '2020-01-08', 0.4 , NULL, NULL)
;

要求列[CB]和[CC]是递归的,以便(在粗略的SQL逻辑中):

  • [Cb]=LAG([CC])*[Ca]
  • [CC]=LAG([CC])+[CB]

因此,列[CB]中的第二个单元格将等于10或100*0.1,而[CC]中的第二个单元格将等于110或100+10。
对于本例,完整的解决方案如下所示:
Date|Ca|Cb|CC
-|-|
2020-01-01|空|空|100.0
2020-01-02|0.1|10.0|110.0
2020-01-03|0.2|22.0|132.0
2020-01-04|0.1|13.2|145.2
2020-01-05|0.4|58.1|203.3
2020-01-06|0.3|61.0|264.3
2020-01-07|0.2|52.9|317.1
2020-01-08|0.4|126.8|444.0
表的长度是动态的,因此递归解也必须是动态的。
我已经通读并探索了SQLite的递归CTE特性,但我似乎想不出如何在视图上下文中应用它。或者,我可能应该以不同的方式来处理这个问题。任何帮助或指导都将不胜感激。

u4vypkhs

u4vypkhs1#

在这种情况下,视图和表之间没有区别。首先,我添加了ROW_NUMBER,这样就可以直接选择rCTE中的下一行。然后你就可以计算你的目标了:

WITH RECURSIVE
    numbered AS (
        SELECT row_number() OVER (ORDER BY "Date") AS idx, * FROM Test
    ),
    new_test AS (
            SELECT * FROM numbered WHERE idx = 1
        UNION ALL
            SELECT
                numbered.idx,
                numbered."Date",
                numbered.Ca,
                new_test.Cc * numbered.Ca AS Cb,
                new_test.Cc + new_test.Cc * numbered.Ca AS Cc
            FROM new_test, numbered
            WHERE numbered.idx = new_test.idx + 1
    )
SELECT "Date", Ca, round(Cb, 1) AS Cb, round(Cc, 1) AS Cc FROM new_test

相关问题