MySQL查询需求:获取每个账户最早的3笔待处理还款记录
MySQL查询:获取每个贷款账户最早的3笔待处理(PENDING)还款记录
要搞定这个「每个贷款账户取最早3笔待处理还款」的需求,MySQL 8.0+的窗口函数ROW_NUMBER() 是最省心高效的方案,比你之前用分组取最小值的方式灵活多了,完全适配还款日期无规律的场景。
最优解决方案(MySQL 8.0+)
SELECT la.id AS `loanaccount.id`, rep.duedate AS `rep.duedate`, rep.principaldue AS `rep.principaldue`, rep.interestdue AS `rep.interestdue`, rep.state AS `rep.state` FROM loanaccount la JOIN ( SELECT *, -- 按贷款账户分组,按还款日期升序分配行号 ROW_NUMBER() OVER ( PARTITION BY parentaccountkey ORDER BY duedate ASC ) AS row_num FROM repayment WHERE state = 'PENDING' -- 只筛选待处理状态的记录 ) rep ON la.encodedkey = rep.parentaccountkey WHERE rep.row_num <= 3 -- 取每个分组的前3条记录 ORDER BY la.id, rep.duedate; -- 按账户ID和还款日期排序,结果更清晰
逻辑说明
- 内层子查询:先对
repayment表中所有PENDING状态的记录,用ROW_NUMBER()窗口函数按parentaccountkey(关联贷款账户的外键)分组,每组内按duedate升序排序,给每条记录分配一个从1开始的行号row_num。 - 外层关联:将子查询结果和
loanaccount表通过外键关联,筛选出行号≤3的记录,也就是每个账户最早的3笔待处理还款。 - 排序输出:最后按账户ID和还款日期排序,让结果更易读。
执行结果
运行上述查询后,会得到你期望的结果:
| loanaccount.id | rep.duedate | rep.principaldue | rep.interestdue | rep.state |
|---|---|---|---|---|
| a1 | 2018-01-01 | 7500.00 | 5000.00 | PENDING |
| a1 | 2018-02-01 | 7500.00 | 4000.00 | PENDING |
| a1 | 2018-03-01 | 6000.00 | 5000.00 | PENDING |
| b2 | 2018-01-01 | 5000.00 | 6500.00 | PENDING |
| b2 | 2018-04-01 | 6500.00 | 5000.00 | PENDING |
| b2 | 2018-08-01 | 4000.00 | 3000.00 | PENDING |
| c3 | 2018-02-01 | 3500.00 | 4000.00 | PENDING |
兼容MySQL 5.x版本的方案
如果你的MySQL版本低于8.0(不支持窗口函数),可以用子查询计数的方式实现,虽然效率稍低,但能兼容旧版本:
SELECT la.id AS `loanaccount.id`, rep1.duedate AS `rep.duedate`, rep1.principaldue AS `rep.principaldue`, rep1.interestdue AS `rep.interestdue`, rep1.state AS `rep.state` FROM loanaccount la JOIN repayment rep1 ON la.encodedkey = rep1.parentaccountkey WHERE rep1.state = 'PENDING' -- 统计当前账户下,还款日期≤当前记录的待处理记录数量 AND ( SELECT COUNT(*) FROM repayment rep2 WHERE rep2.parentaccountkey = rep1.parentaccountkey AND rep2.state = 'PENDING' AND rep2.duedate <= rep1.duedate ) <= 3 ORDER BY la.id, rep1.duedate;
这个方案的逻辑是:对每一条待处理还款记录,统计同一个账户下还款日期不晚于当前记录的待处理记录总数,如果总数≤3,说明这条记录属于该账户最早的3笔之一。
内容的提问来源于stack exchange,提问作者monkeyb33f
相关产品推荐
相关产品推荐

