如何编写单条SQL语句实现每个citycode对应返回前20行数据
实现方案
完全可以通过单条SQL实现需求,根据你使用的数据库版本不同,可选两种实现方式:
通用窗口函数方案(支持MySQL8.0+、PostgreSQL、Oracle、SQL Server等所有主流新版数据库)
SELECT name, citycode FROM ( SELECT name, citycode, ROW_NUMBER() OVER (PARTITION BY citycode ORDER BY rank ASC) AS group_rn FROM tab20 WHERE rank <= 20 ) t WHERE group_rn <= 20;
- 内层查询先通过
PARTITION BY citycode按城市编码分组,组内按rank从小到大排序生成组内唯一序号group_rn,同时提前过滤全局rank大于20的行减少计算量 - 外层查询仅保留每个分组内序号前20的行,即可得到每个citycode对应的最多20条符合要求的数据
- 如果同一个citycode下相同rank的行需要全部保留,可以把
ROW_NUMBER()替换为RANK()或者DENSE_RANK(),按需调整即可
老版本无窗口函数数据库适配方案(例如MySQL5.x及更早版本)
SELECT t1.name, t1.citycode FROM tab20 t1 WHERE t1.rank <= 20 AND ( SELECT COUNT(*) FROM tab20 t2 WHERE t2.citycode = t1.citycode AND t2.rank <= 20 AND t2.rank <= t1.rank ) <= 20 ORDER BY t1.citycode, t1.rank;
- 不需要提前枚举所有citycode拼接union,自动适配任意数量的城市编码场景
内容的提问来源于stack exchange,提问作者ninjaloot777
相关产品推荐
相关产品推荐

