Reputation: 111
I have a task involving Postgresql database. I am not very experienced with SQL.
I have a table with weekly turnover of trade products.
For each week, the following information is provided: product, week number, weekly turnover (may be positive or negative, depending on weather more of the product has been purchased or sold). I have added a column with closing balance for each week. I have a closing balance in the table for all product for first week (week_number = 0), but "null" for all other weeks. A few exemplary records are provided below.
product | week_number | turnover | closing_balace
--------------------------------+-------------+----------+----------------
BLGWK-05.00*1250*KR-S235JRN0-A | 0 | 50.00 | 1240.00
BLGWK-05.00*1250*KR-S355J2CN-K | 0 | 45.70 | 455.75
BLGWK-05.00*1464*KR-DD11NIET-K | 0 | 30.01 | 300.00
BLGWK-05.00*1500*KR-DD11NIET-R | 1 | 10.22 |
BLGWK-05.00*1500*KR-S235J2CU-K | 1 | 88.00 |
I need a query to fill in all the "null" closing_balance's with following computation:
closing_balance = closing_balance of the same product for previous week + turnover for the week.
I tried this query:
update table_turnover
set closing_balance = (select lag(closing_balance, 1) over (partition by product order by week_number) + turnover)
where week_number > 0;
It never worked - the "null" values for closing_balance above "week 0" remained "null".
I also tried:
update table_turnover
set closing_balance = (select
case when week_number = 0
then closing_balance
else (lag(closing_balance, 1) over (partition by product order by week_number) + turnover)
end
from table_turnover)
This one generates an error
more than one record returned by sub-query used as expression
Any idea how to do this computation?
Thank you in advance.
Upvotes: 3
Views: 2460
Reputation: 1270513
Use a subquery in the from
clause:
update table_turnover
set closing_balance = (ttprev.prev_closing_balance + ttprev.turnover)
from (select tt.*,
lag(closing_balance) over (partition by product order by
week_number) as prev_closing_balance
from table_turnover tt
) ttprev
where ttprev.product = tt.product and ttprev.week_number = tt.week_number and
week_number > 0;
Or, if you want to use a subquery in the select
:
update table_turnover
set closing_balance = (turnover +
(select tt2.closing_balance
from table_turnover tt2
where tt2.product = tt.product and tt2.week_number = tt.week_number - 1
)
)
where week_number > 0;
For performance (on either version), you want an index on table_turnover(product, week_number, closing_balance)
.
Upvotes: 2