简体   繁体   中英

How to calculate total balance in sql using sum?

updated question --

I have a table that contains the following columns:

DROP TABLE TABLE_1;
CREATE TABLE TABLE_1(
TRANSACTION_ID number, USER_KEY number,AMOUNT number,CREATED_DATE DATE, UPDATE_DATE DATE
);

insert into TABLE_1
values ('001','1001',75,'2022-12-02','2022-12-03'),
('001','1001',-74.98,'2022-12-02','2022-12-03'),
('001','1001',74.98,'2022-12-03','2022-12-04'),
('001','1001',-75,'2022-12-03','2022-12-04')

I need to calculate the balance based on the update date. In some cases there can be the same update_date for two different records. When I have this, I want to grab the lower value of the balance.

This is the query I have so far:

select * from (
select TRANSACTION_ID,USER_KEY,AMOUNT,CREATED_DATE,UPDATE_DATE,
sum(AMOUNT) over(partition by USER_KEY order by UPDATE_DATE rows BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as TOTAL_BALANCE_AMOUNT
from TABLE_1
) qualify row_number() over (partition by USER_KEY order by UPDATE_DATE DESC, UPDATE_DATE DESC) = 1

In the query above, it's is grabbing the 75, rather than the 0 after I try to only grab the LAST balance.

Is there a way to include in the qualify query to grab the last balance but if the dates are the same, to grab the lowest balance?

why is the second query, showing 4 different record balances?

That is the point of "running total". If the goal is to have a single value per entire window then order by should be skipped:

select USER_KEY, 
       sum(AMOUNT) over(partition by USER_KEY) as TOTAL_BALANCE_AMOUNT
from TABLE1;

The partition by clause could be futher expanded with date to produce output per user_key/date:

select USER_KEY, 
       sum(AMOUNT) over(partition by USER_KEY,date) as TOTAL_BALANCE_AMOUNT
from TABLE1;

I think you're looking for something like this, aggregate by USER_ID, DATE, and then calculate a running sum. If this is not what you're looking for nor is Lukasz Szozda's answer, please edit the question to show the intended output.

    create or replace table T1(USER_KEY int, AMOUNT number(38,2), "DATE" date);
    
    insert into T1(USER_KEY, AMOUNT, "DATE") values
    (1001, 75,  '2022-12-02'),
    (1001, -75, '2022-12-02'),
    (1001, 75,  '2022-12-03'),
    (1001, -75, '2022-12-03');
    
-- Option 1, aggregate after window
select USER_KEY, "DATE", min(TOTAL_BALANCE_AMOUNT) as MINIMUM_BALANCE from 
(
select USER_KEY, "DATE", sum(AMOUNT)
over(partition by USER_KEY order by DATE, AMOUNT desc rows BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as TOTAL_BALANCE_AMOUNT from
T1
)
group by USER_KEY, "DATE"
;

--Option 2, qualify by partitioning by user and day, reversing the order of transactions
select USER_KEY, "DATE", sum(AMOUNT)
over(partition by USER_KEY order by DATE, AMOUNT desc rows BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as TOTAL_BALANCE_AMOUNT
from
T1
qualify row_number() over (partition by USER_KEY, DATE order by DATE, AMOUNT asc) = 1
;
USER_KEY DATE TOTAL_BALANCE_AMOUNT
1001 2022-12-02 00:00:00 0
1001 2022-12-03 00:00:00 0

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