如何在 SQLite 中计算不同利率的复利

Sam*_*ert 2 sql sqlite

我需要按产品计算复利,其中利率可能因年份而异。

简化表如下。initial_value是产品在第一年年初的价值,final_value是包括相应年末利息的价值。

product year    initial_value   interest    final_value
a         1       10000           0.03        10,300.00
a         2                       0.02        10,506.00
a         3                       0.01        10,611.06
b         1       15000           0.04        15,600.00
b         2                       0.06        16,536.00
b         3                       0.07        17,693.52
Run Code Online (Sandbox Code Playgroud)

重新创建表:

CREATE TABLE temp (year INTEGER, product CHARACTER,
                   initial_value DECIMAL(10,2), interest DECIMAL(10,2));

INSERT INTO temp VALUES (1, 'a', 10000, 0.03);
INSERT INTO temp VALUES (2, 'a', 0, 0.02);
INSERT INTO temp VALUES (3, 'a', 0, 0.01);

INSERT INTO temp VALUES (1, 'b', 15000, 0.04);
INSERT INTO temp VALUES (2, 'b', 0, 0.06);
INSERT INTO temp VALUES (3, 'b', 0, 0.07);
Run Code Online (Sandbox Code Playgroud)

以product = a为例,第3年的数字应计算为10000 * (1+0.03) * (1+0.02) * (1+0.01)

产品的年份和数量可能会有所不同,因此我想避免按年份转置数据,但遗憾的是无法想到另一种方法来跨行相乘以获得所需的结果。

Luk*_*zda 7

你可以使用RECURSIVE CTE

\n\n
WITH RECURSIVE cte AS (\n  SELECT year, product, initial_value, interest, initial_value*(1+ interest) AS s\n  FROM temp\n  WHERE initial_value <> 0\n  UNION ALL\n  SELECT t.year, t.product, t.initial_value, t.interest, s * (1+t.interest)\n  FROM temp t\n  JOIN cte c\n    ON t.product = c.product\n    AND t.year = c.year+1\n)\nSELECT *\nFROM cte\nORDER BY product, year;\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 year \xe2\x94\x82 product \xe2\x94\x82 initial_value \xe2\x94\x82 interest \xe2\x94\x82 final_value \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82    1 \xe2\x94\x82 a       \xe2\x94\x82         10000 \xe2\x94\x82     0.03 \xe2\x94\x82       10300 \xe2\x94\x82\n\xe2\x94\x82    2 \xe2\x94\x82 a       \xe2\x94\x82             0 \xe2\x94\x82     0.02 \xe2\x94\x82       10506 \xe2\x94\x82\n\xe2\x94\x82    3 \xe2\x94\x82 a       \xe2\x94\x82             0 \xe2\x94\x82     0.01 \xe2\x94\x82    10611.06 \xe2\x94\x82\n\xe2\x94\x82    1 \xe2\x94\x82 b       \xe2\x94\x82         15000 \xe2\x94\x82     0.04 \xe2\x94\x82       15600 \xe2\x94\x82\n\xe2\x94\x82    2 \xe2\x94\x82 b       \xe2\x94\x82             0 \xe2\x94\x82     0.06 \xe2\x94\x82       16536 \xe2\x94\x82\n\xe2\x94\x82    3 \xe2\x94\x82 b       \xe2\x94\x82             0 \xe2\x94\x82     0.07 \xe2\x94\x82    17693.52 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n\n

DBFiddle 演示

\n\n
\n\n

编辑

\n\n

只是为了纯粹的乐趣,我使用窗口函数重写了它:

\n\n
SELECT *,\n    FIRST_VALUE(initial_value) OVER(PARTITION BY product ORDER BY year) \n    * exp (sum (ln (1+interest)) OVER(PARTITION BY product ORDER BY year))\nFROM temp;\n
Run Code Online (Sandbox Code Playgroud)\n\n

DBFiddle 演示2 - PostgreSQL

\n