如何按用户及财年获取最新余额及对应更新日期
获取每个用户各财年的最新余额及对应更新日期
我有一张名为balances的表,需要获取每个用户在每个财年(financial_year)的最新余额(balance)及其对应的更新日期(date_updated)。
表结构与数据
| name | balance | financial_year | date_updated |
|---|---|---|---|
| Bob | 20 | 2021 | 2021-04-03 |
| Bob | 58 | 2019 | 2019-11-13 |
| Bob | 43 | 2019 | 2022-01-24 |
| Bob | -4 | 2019 | 2019-12-04 |
| James | 92 | 2021 | 2021-09-11 |
| James | 86 | 2021 | 2021-08-18 |
| James | 33 | 2019 | 2019-03-24 |
| James | 46 | 2019 | 2019-02-12 |
| James | 59 | 2019 | 2019-08-12 |
期望输出
| name | balance | financial_year | date_updated |
|---|---|---|---|
| Bob | 20 | 2021 | 2021-04-03 |
| Bob | 43 | 2019 | 2022-01-24 |
| James | 92 | 2021 | 2021-09-11 |
| James | 59 | 2019 | 2019-08-12 |
问题所在
我尝试了以下SQL语句,但发现用max()函数跨多列查询无法得到正确结果:
SELECT name, max(balance), financial_year, max(date_updated) FROM balances group by name, financial_year
这是因为max(balance)和max(date_updated)可能来自表中不同的行,并不是同一个最新记录的对应值。
解决方案
方法1:使用窗口函数ROW_NUMBER()(推荐,适用于大多数现代数据库)
通过窗口函数按用户和财年分组,对每个分组内的记录按date_updated倒序排序,取排序为1的记录(即最新的那条):
SELECT name, balance, financial_year, date_updated FROM ( SELECT name, balance, financial_year, date_updated, ROW_NUMBER() OVER (PARTITION BY name, financial_year ORDER BY date_updated DESC) AS rn FROM balances ) t WHERE rn = 1;
方法2:子查询关联(兼容旧版数据库)
先找出每个用户+财年组合的最新更新日期,再关联原表获取对应的余额:
SELECT b.name, b.balance, b.financial_year, b.date_updated FROM balances b INNER JOIN ( SELECT name, financial_year, MAX(date_updated) AS latest_date FROM balances GROUP BY name, financial_year ) t ON b.name = t.name AND b.financial_year = t.financial_year AND b.date_updated = t.latest_date;
方法3:使用CTE(更清晰的结构)
和方法1逻辑一致,用CTE替代子查询:
WITH ranked_balances AS ( SELECT name, balance, financial_year, date_updated, ROW_NUMBER() OVER (PARTITION BY name, financial_year ORDER BY date_updated DESC) AS rn FROM balances ) SELECT name, balance, financial_year, date_updated FROM ranked_balances WHERE rn = 1;
内容的提问来源于stack exchange,提问作者Zoey Malkov
相关产品推荐
相关产品推荐

