如何在SQL中按table_2_id分组保留每组最大id的前5行?
解决方案:按分组保留每组Top N记录
这是个很典型的分组取Top N的需求,用SQL的窗口函数就能完美解决,我给你写个具体的实现:
核心思路
我们可以用ROW_NUMBER()窗口函数,先给每个table_2_id分组内的记录按id降序排名,然后筛选出排名前5的记录即可。
完整SQL代码
-- 先给每条记录按分组和id降序分配排名 WITH ranked_data AS ( SELECT id, table_2_id, name, -- 按table_2_id分组,组内按id从大到小排序,生成排名 ROW_NUMBER() OVER (PARTITION BY table_2_id ORDER BY id DESC) AS rank_num FROM your_table -- 这里替换成你的实际表名 ) -- 筛选出每个分组内排名前5的记录 SELECT id, table_2_id, name FROM ranked_data WHERE rank_num <= 5 -- 最后按分组和id排序,让结果更规整 ORDER BY table_2_id, id;
代码解释
PARTITION BY table_2_id:把整个数据集按照table_2_id拆分成独立的分组,每个分组单独处理ORDER BY id DESC:在每个分组内部,按照id从大到小排序,这样最大的id会得到排名1,次大的是2,以此类推ROW_NUMBER():给每个分组内的每条记录分配一个唯一的排名值- 最后通过
WHERE rank_num <=5筛选出每个分组里排名前5的记录,也就是id最大的5条
用你的测试数据跑这个SQL,得到的结果正好和你期望的一致:
id | table_2_id | name
3 | 1 |C
4 | 1 |D
5 | 1 |E
6 | 1 |F
7 | 1 |F
8 | 2 |G
9 | 3 |H
10 | 3 |I
如果你的场景中存在id重复的情况(虽然通常id是主键不会重复),可以把ROW_NUMBER()换成RANK()或者DENSE_RANK(),这样相同id的记录会得到相同的排名,避免误删。
内容的提问来源于stack exchange,提问作者alix-bourree
相关产品推荐
相关产品推荐

