You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL多字段GROUP BY查询获取各年月胜场最高选手的实现方法

月度乒乓球最高胜场选手统计SQL实现

场景说明

正在开发乒乓球计分板功能,需要按自然月维度统计每个月胜场数最高的获奖选手。

现有基础统计

目前已编写的分组统计SQL可以算出每个选手在对应年月的总胜场数,语句如下:
SELECT COUNT(winner) as wins, winner as player, YEAR(recorded) as year, MONTH(recorded) as month FROM matches GROUP BY winner, YEAR(recorded), MONTH(recorded)
实际执行后的返回结果为:

+------+--------+------+-------+
| wins | player | year | month |
+------+--------+------+-------+
|    7 |     21 | 2021 |     1 |
|    4 |     19 | 2021 |     1 |
|    1 |     20 | 2021 |     1 |
|   78 |     20 | 2021 |     2 |
|   46 |     19 | 2021 |     2 |
|   84 |     21 | 2021 |     2 |
|    4 |     23 | 2021 |     2 |
|    2 |     26 | 2021 |     2 |
|    5 |     20 | 2021 |     3 |
|    9 |     21 | 2021 |     3 |
|    9 |     20 | 2021 |     4 |
|   10 |     21 | 2021 |     4 |
|    8 |     19 | 2021 |     4 |
+------+--------+------+-------+

筛选目标

需要从上述统计结果中,筛出每个年份+月份维度下胜场数最高的记录,最终预期输出格式为:

+------+--------+------+-------+
| wins | player | year | month |
+------+--------+------+-------+
|    7 |     21 | 2021 |     1 |
|   84 |     21 | 2021 |     2 |
|    9 |     21 | 2021 |     3 |
|   10 |     21 | 2021 |     4 |
+------+--------+------+-------+

可行SQL实现方案

方案1:窗口函数实现(适配MySQL 8.0及以上版本)

基于已有的分组统计结果,用窗口函数按照年、月维度分区,对胜场数做降序排序,取分区内排名第一的记录即可,逻辑简洁、查询性能更好:

WITH monthly_win_count AS (
    SELECT 
        COUNT(winner) as wins, 
        winner as player, 
        YEAR(recorded) as year, 
        MONTH(recorded) as month 
    FROM `matches` 
    GROUP BY winner, YEAR(recorded), MONTH(recorded)
)
SELECT wins, player, year, month
FROM (
    SELECT 
        *,
        RANK() OVER (PARTITION BY year, month ORDER BY wins DESC) as win_rank
    FROM monthly_win_count
) ranked_result
WHERE win_rank = 1

注意:如果遇到同一月份多个选手胜场数并列最高的情况,RANK()函数会保留所有并列第一的记录,能适配实际比赛中并列获奖的业务场景。如果需要强制只取一条记录,可以把RANK()换成ROW_NUMBER()函数。

方案2:关联最大值匹配(兼容所有MySQL版本,含5.x系列)

如果使用的是不支持窗口函数的低版本数据库,可以先按年、月分组算出每个月的最高胜场数,再关联回原统计结果匹配对应的选手:

SELECT base.wins, base.player, base.year, base.month
FROM (
    -- 每个选手的月度胜场统计
    SELECT 
        COUNT(winner) as wins, 
        winner as player, 
        YEAR(recorded) as year, 
        MONTH(recorded) as month 
    FROM `matches` 
    GROUP BY winner, YEAR(recorded), MONTH(recorded)
) base
INNER JOIN (
    -- 每个年月对应的最高胜场数
    SELECT year, month, MAX(wins) as max_wins
    FROM (
        SELECT 
            COUNT(winner) as wins, 
            YEAR(recorded) as year, 
            MONTH(recorded) as month 
        FROM `matches` 
        GROUP BY winner, YEAR(recorded), MONTH(recorded)
    ) win_base
    GROUP BY year, month
) month_max
ON base.year = month_max.year 
   AND base.month = month_max.month 
   AND base.wins = month_max.max_wins

内容的提问来源于stack exchange,提问作者Mikkel Holmberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 13:06:05