MySQL技术问题:按region提取wins排名前二的age_group
MySQL按地区提取wins前两名年龄组的查询方案
假设你的数据表名为player_stats(可根据实际修改),包含字段region、age_group、wins,以下提供两种可行方案:
方案一:使用窗口函数(MySQL 8.0+ 推荐)
利用ROW_NUMBER()窗口函数为每个地区内的年龄组按wins降序排名,再通过条件聚合将前两名转为列:
SELECT region, MAX(CASE WHEN rn = 1 THEN age_group END) AS `最佳年龄组`, MAX(CASE WHEN rn = 2 THEN age_group END) AS `次佳年龄组` FROM ( SELECT region, age_group, wins, -- 按地区分组,按wins降序生成排名 ROW_NUMBER() OVER (PARTITION BY region ORDER BY wins DESC) AS rn FROM player_stats ) ranked_data WHERE rn <= 2 GROUP BY region;
说明:
- 如果存在多个年龄组
wins相同的情况,ROW_NUMBER()会随机分配排名(仅取其中一个);若需保留并列排名,可替换为RANK()或DENSE_RANK(),但此时同一地区可能出现多个"最佳年龄组",需根据实际需求调整聚合逻辑(比如用GROUP_CONCAT拼接并列项)。 - 若某地区仅存在1个年龄组,
次佳年龄组字段会返回NULL。
方案二:变量模拟排名(MySQL 5.x 兼容)
针对不支持窗口函数的老版本MySQL,使用用户变量手动计算排名:
SELECT region, MAX(CASE WHEN rn = 1 THEN age_group END) AS `最佳年龄组`, MAX(CASE WHEN rn = 2 THEN age_group END) AS `次佳年龄组` FROM ( SELECT region, age_group, -- 当地区不变时排名递增,切换地区时重置为1 @rn := IF(@current_region = region, @rn + 1, 1) AS rn, @current_region := region FROM player_stats -- 初始化变量 CROSS JOIN (SELECT @current_region := '', @rn := 0) init_vars -- 按地区和wins降序排序,确保排名逻辑正确 ORDER BY region, wins DESC ) ranked_data WHERE rn <= 2 GROUP BY region;
注意事项:
- 必须保证子查询中的
ORDER BY region, wins DESC执行顺序优先于变量赋值,否则排名会出错。 - 同方案一,若需处理并列排名,需调整变量逻辑或聚合方式。
内容的提问来源于stack exchange,提问作者permanewb
相关产品推荐
相关产品推荐

