基于EFFDT列获取ACCT表最新账户记录的SQL实现问题
获取每组账户最新记录的SQL实现方案
嘿,我来帮你搞定这个SQL需求~你要从ACCT表中按COMPANY和ACCOUNT分组,取出每组里EFFDT最新的那条完整记录对吧?下面给你两种常用且靠谱的实现方式:
方案一:使用窗口函数(推荐,灵活易用)
现在绝大多数主流数据库(比如MySQL 8+、PostgreSQL、SQL Server、Oracle)都支持窗口函数,用ROW_NUMBER()可以轻松实现需求:
SELECT COMPANY, ACCOUNT, EFFDT, NAME FROM ( SELECT *, -- 按公司+账户分组,每组内按日期倒序编号,最新的记录编号为1 ROW_NUMBER() OVER (PARTITION BY COMPANY, ACCOUNT ORDER BY EFFDT DESC) AS record_rank FROM ACCT ) ranked_records WHERE record_rank = 1;
补充说明:
- 如果同一
(COMPANY, ACCOUNT)组内有多条记录的EFFDT完全相同(即同一天的多条记录),ROW_NUMBER()会随机给它们分配不同的编号,最终只返回其中一条。要是你想保留所有同日期的最新记录,可以把ROW_NUMBER()换成RANK()或者DENSE_RANK(),筛选条件不变。
方案二:关联子查询(兼容性好,适合老版本数据库)
如果你用的是不支持窗口函数的老版本数据库,比如MySQL 5.x,那可以用分组子查询+关联的方式实现:
SELECT t1.* FROM ACCT t1 INNER JOIN ( -- 先算出每个公司+账户组的最新日期 SELECT COMPANY, ACCOUNT, MAX(EFFDT) AS latest_effdt FROM ACCT GROUP BY COMPANY, ACCOUNT ) t2 ON t1.COMPANY = t2.COMPANY AND t1.ACCOUNT = t2.ACCOUNT AND t1.EFFDT = t2.latest_effdt;
补充说明:
- 这种方式如果遇到同一组内有多个相同最新日期的记录,会返回所有这些记录,和用
RANK()的效果一致。
验证你的样本数据
用上面任意一种SQL执行你提供的样本数据,都会得到所有组的最新记录:
| COMPANY | ACCOUNT | EFFDT | NAME |
|---|---|---|---|
| 25 | 1001 | 2015-12-01 | ABC Ltd. |
| 30 | 1001 | 2012-01-01 | ABC Inc |
| 10 | 1001 | 2012-01-01 | ABC Inc |
| 10 | 3800 | 2011-05-01 | RAC Corp |
| 25 | 3800 | 2011-05-01 | RAC Corp |
| 30 | 3800 | 2011-05-01 | RAC Corp |
你给出的期望结果只列了两条,应该是示例部分数据,实际执行会返回所有符合条件的记录哦~
内容的提问来源于stack exchange,提问作者Bala
相关产品推荐
相关产品推荐

