Reputation: 341
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?
Upvotes: 0
Views: 473
Reputation: 11046
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 |
Upvotes: 1
Reputation: 175616
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;
Upvotes: 2