Как рассчитать сложные проценты с различными процентными ставками в SQLite - PullRequest
0 голосов
/ 26 мая 2018

Мне нужно рассчитать сложную процентную ставку по продуктам, где процентная ставка может варьироваться в зависимости от года.

Упрощенная таблица ниже.initial_value - это стоимость продукта на начало 1 года, 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

Чтобы воссоздать таблицу:

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);

для продукта = a, например, число в 3 году следует рассчитать как 10000 * (1+0.03) * (1+0.02) * (1+0.01)

Годы иКоличество продуктов может варьироваться, поэтому я хочу избежать переноса данных по годам, но, к сожалению, не могу придумать другой способ умножения по строкам для достижения желаемого результата.

1 Ответ

0 голосов
/ 26 мая 2018

Вы можете использовать RECURSIVE CTE:

WITH RECURSIVE cte AS (
  SELECT year, product, initial_value, interest, initial_value*(1+ interest) AS s
  FROM temp
  WHERE initial_value <> 0
  UNION ALL
  SELECT t.year, t.product, t.initial_value, t.interest, s * (1+t.interest)
  FROM temp t
  JOIN cte c
    ON t.product = c.product
    AND t.year = c.year+1
)
SELECT *
FROM cte
ORDER BY product, year;

Выход:

┌──────┬─────────┬───────────────┬──────────┬─────────────┐
│ year │ product │ initial_value │ interest │ final_value │
├──────┼─────────┼───────────────┼──────────┼─────────────┤
│    1 │ a       │         10000 │     0.03 │       10300 │
│    2 │ a       │             0 │     0.02 │       10506 │
│    3 │ a       │             0 │     0.01 │    10611.06 │
│    1 │ b       │         15000 │     0.04 │       15600 │
│    2 │ b       │             0 │     0.06 │       16536 │
│    3 │ b       │             0 │     0.07 │    17693.52 │
└──────┴─────────┴───────────────┴──────────┴─────────────┘

DBFiddle Demo


РЕДАКТИРОВАТЬ

Просто для развлечения я переписал его с помощью оконных функций:

SELECT *,
    FIRST_VALUE(initial_value) OVER(PARTITION BY product ORDER BY year) 
    * exp (sum (ln (1+interest)) OVER(PARTITION BY product ORDER BY year))
FROM temp;

DBFiddle Demo2 - PostgreSQL

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...