I have a table like this:
Table "*wallet"
amount | balance | timestamp |
---|---|---|
1000 | 1000 | 2023-01-25 21:41:39 |
-1000 | 0 | 2023-01-25 21:41:40 |
200000 | 200000 | 2023-01-25 22:30:10 |
10000 | 210000 | 2023-01-26 08:12:05 |
5000 | 215000 | 2023-01-26 09:10:12 |
And here is the expected result: (one row per day)
min_balance | last_balance | date |
---|---|---|
0 | 200000 | 2023-01-25 |
210000 | 215000 | 2023-01-26 |
Here is my current query:
SELECT MIN(balance) min_balance,
DATE(timestamp) date
FROM wallet
GROUP BY date
How can I add last_balance
? Sadly there is no something like LAST(balance)
in MySQL. By "last" I mean bigger timestamp
.
CodePudding user response:
With MIN()
and FIRST_VALUE()
window functions:
SELECT DISTINCT
MIN(balance) OVER (PARTITION BY DATE(timestamp)) AS min_balance,
FIRST_VALUE(balance) OVER (PARTITION BY DATE(timestamp) ORDER BY timestamp DESC) AS last_balance,
DATE(timestamp) AS date
FROM wallet;
See the demo.
CodePudding user response:
If you are running MySQL 8 or later, then we can use ROW_NUMBER()
here:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY DATE(timestamp) ORDER BY balance) rn_min,
ROW_NUMBER() OVER (PARTITION BY DATE(timestamp) ORDER BY timestamp DESC) rn_last
FROM yourTable
)
SELECT
DATE(timestamp) AS date,
MAX(CASE WHEN rn_min = 1 THEN balance END) AS min_balance,
MAX(CASE WHEN rn_last = 1 THEN balance END) AS last_balance
FROM cte
GROUP BY 1
ORDER BY 1;