简体   繁体   中英

Calculate row value based on previous row values in Oracle SQL

I have a problem with identification of the final reduced price. I have years and discounts per year. So, I need to find out what is going to be the final price in the last year. If in one year I have a discount, then I need to have the discounted price for the next years as well and not the original price. As it is in the attached screenshot, you can see that in 2022 and 2023 I have a discount by 5% but in both years it results the same value because 5% is reduced from the original price, although in 2023 it had to reduce 5% from already reduced price in 2022. In 2024 I have 0% discount, so I need to have the value of 2023 in 2024. In 2025 I have a discount of 2%, so it should be reduced from the value of 2024. Here is the code:

select k.object_number, k.plant, k.company, k.discount, k.demand, k.year, k.Price, 
      case when (k.discount) is null then k.price else k.price * (100-k.discount)/100 end as Reduced_price    
from K_TABLE as K
order by k.year`

Sample of actual result:

Object Number     Plant      Company     Demand   Year     Discount   Price     Reduced Price
    1A                30          ABC         790      2021     0          45,88     45,88           1A                30          ABC         17587    2022     5          45,88     43,586       1A                21          ABC         7824     2022     5          45,88     43,586           1A                63          ABC         12038    2023     5          45,88     43,586         1A                30          ABC         21039    2023     5          45,88     43,586        1A                30          ABC         24299    2024     0          45,88     45,88         1A                37          ABC         17257    2024     0          45,88     45,88          1A                83          ABC         3060     2025     2          45,88     44,9624       1A                21          ABC         49647    2025     2          45,88     44,9624      1A                30          ABC         19904    2026     0          45,88     45,88                                       

Please check the attached screenshot for the full result.`

在此处输入图像描述

You can calculate the total discount using arithmetic -- that is logs and exponents:

select k.*,
       (1 - exp(sum(ln(1 - discount / 100)) over (partition by object_number, plant, company order by year)
       ) as total_discount,
       (price *
        exp(sum(ln(1 - coalesce(discount, 0) / 100)) over (partition by object_number, plant, company order by year)
       ) as reduced_price
from K_TABLE as K
order by k.year;

The exp(sum(ln(. . . ))) expression is doing a cumulative product. That is not built into SQL, but it can be calculating using mathematical operations.

Note: it is hard to tell what that "unit" is in your data -- that is, what constitutes the "next" row for the same unit. I am assuming it is the combination of object, plant, and company. However, I would expect something like a "product" column that has the information in a single column.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM