MySQL分组后取每组前N条记录

33 阅读2分钟

问题描述

最近需要对产品进行抽样调查, 给的取数逻辑是产品上线以来, 每天取任意5笔借据的信息

案例如下

字段说明: id: 记录的唯一标识符
contract_no : 借据号
batch_id : 该借据对应的放款记账日

表结构如下:

idcontract_nobatch_id
1借据号00120250101
2借据号00220250101
3借据号00320250101
4借据号00420250101
5借据号00520250101
6借据号00620250101
7借据号00720250101
8借据号00820250102
9借据号00920250102
10借据号01020250102
11借据号01120250102
12借据号01220250102
13借据号01320250102
14借据号01420250103

解决方案

使用 ROW_NUMBER() 函数, 将整张表的数据根据日期分组后, 每个日期的分组里面, 每条记录加上一个排序字段

查询 sql 如下:

SELECT *,
ROW_NUMBER() OVER (PARTITION BY batch_id ORDER BY id DESC) AS rn
FROM '要查询的表'
-- 仅对 20250101之后的数据进行每天抽样
WHERE batch_id >= '20250101'

查询结果如下:

idcontract_nobatch_idrn
1 借据号001202501011
2借据号002202501012
3借据号003202501013
4借据号004202501014
5借据号005202501015
6借据号006202501016
7借据号007202501017
8借据号008202501021
9借据号009202501022
10借据号010202501023
11借据号011202501024
12借据号012202501025
13借据号013202501026
14借据号014202501031

而需求要查的就是上面表格中标红部分的记录, 所以在这张临时表基础上再加一条筛选条件即可, sql 如下:

SELECT t.*
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY batch_id ORDER BY id DESC) AS rn
FROM '要查询的表'
) AS t
WHERE t.rn <= 5;