【问题标题】:Oracle SQL Missing Years Calculate Last Value and Compound InterestOracle SQL 缺失年份计算最后价值和复利
【发布时间】:2021-09-09 15:19:01
【问题描述】:

我在 Oracle 中有下表:

F1 F2 YEAR AMT
DC1 123 2021 1000
DC1 123 2022 1100
DC1 123 2023
DC1 123 2024
DC2 456 2021 5000
DC2 456 2022 6000
DC2 456 2023
DC2 456 2024

我想根据最后一个可用日期 (YEAR 2022) 的 AMT 计算每个 F1F2 分组的缺失年份 (YEAR 2023 和 2024) 并乘以 AMT每年复利 2.1%。

我用过LAST_VALUE函数

`(LAST VALUE(AMT IGNORE NULLS) OVER (PARTITION BY F1, F2 ORDER BY F1 F2 YEAR ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS NEXT_AMT` 

获取每个分组的最后一个值(1100 和 6000),但是当我乘以 2.1% 时,我没有得到复利效应。

期望的输出:

F1 F2 YEAR AMT NEXT_AMT NEW_AMT
DC1 123 2021 1000 1000
DC1 123 2022 1100 1100
DC1 123 2023 1100 1123.1
DC1 123 2024 1100 1146.68
DC2 456 2021 5000 5000
DC2 456 2022 6000 6000
DC2 456 2023 6000 6126
DC2 456 2024 6000 6254.65

【问题讨论】:

    标签: sql oracle lag


    【解决方案1】:

    计算比率,然后使用算术进行乘法:

    with t as (
          select t.*,
                 max(case when year = 2022 then amt end) over (partition by f1, f2) as year_2022,
                 (max(case when year = 2022 then amt end) over (partition by f1, f2) /
                  max(case when year = 2021 then amt end) over (partition by f1, f2)
                 ) as ratio
          from mytable t
         )
    select t.*,
           coalesce(amt,
                    year_2022 * power(ratio, year - 2022)
                   ) as new_amt
    from t;
    

    编辑:

    糟糕,我误读了这个问题。你实际上有一个固定的比例来增加金额。这更容易:

    with t as (
          select t.*,
                 max(case when year = 2022 then amt end) over (partition by f1, f2) as year_2022
          from mytable t
         )
    select t.*,
           coalesce(amt,
                    year_2022 * power(1.021, year - 2022)
                   ) as new_amt
    from t;
    

    我也意识到你可能不想硬编码 2022。所以:

    with t as (
          select t.*,
                 last_value(case when amt is not null then year end ignore nulls) over (partition by f1, f2 order by year) as last_year,
                 last_value(amt ignore nulls) over (partition by f1, f2 order by amt) as last_year_amt
          from mytable t
         )
    select t.*,
           coalesce(amt,
                    last_year_amt * power(1.021, year - last_year)
                   ) as new_amt
    from t;
    

    Here 是一个 dbfiddle。

    【讨论】:

    • 谢谢!最后一个解决方案效果很好,因为我不需要硬编码任何东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-10
    • 2019-11-18
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    • 2020-02-25
    相关资源
    最近更新 更多