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

MySQL技术求助:统计玩家赛事获胜次数,每对手仅计首次结果

嘿,我来帮你解决这个玩家获胜次数统计的问题!你的需求核心是每对玩家只取最早对战的结果来统计获胜次数,用窗口函数来处理这个场景会比单纯的ORDER BY更高效且逻辑清晰,下面是具体的解决方案:

解决方案步骤

1. 先筛选每对玩家的最早对战记录

首先我们需要确保每两名玩家之间只保留gametime最早的那场对战。这里用LEAST()和GREATEST()函数把玩家对统一成无序的组合(比如player1=A, player2=B和player1=B, player2=A会被视为同一组),再通过ROW_NUMBER()窗口函数为每组记录按时间排序,标记出最早的那条记录:

WITH earliest_battles AS (
    SELECT 
        player1,
        player2,
        result,
        -- 按玩家对分组,按对战时间升序排序,标记最早的记录为rn=1
        ROW_NUMBER() OVER (
            PARTITION BY LEAST(player1, player2), GREATEST(player1, player2)
            ORDER BY gametime ASC
        ) AS rn
    FROM battles
)

2. 基于最早对战记录统计获胜次数

接下来从筛选后的最早对战记录里,把获胜的玩家提取出来并统计次数。根据你的描述,result=1代表player1获胜;如果存在player2获胜的场景(比如result=2,你可以根据实际业务调整这个值),也需要纳入统计:

WITH earliest_battles AS (
    SELECT 
        player1,
        player2,
        result,
        ROW_NUMBER() OVER (
            PARTITION BY LEAST(player1, player2), GREATEST(player1, player2)
            ORDER BY gametime ASC
        ) AS rn
    FROM battles
)
SELECT 
    player_id,
    COUNT(*) AS win_count
FROM (
    -- 收集player1获胜的记录
    SELECT player1 AS player_id 
    FROM earliest_battles 
    WHERE rn = 1 AND result = 1
    
    UNION ALL
    
    -- 收集player2获胜的记录(如果有对应result值的话,这里假设是result=2)
    SELECT player2 AS player_id 
    FROM earliest_battles 
    WHERE rn = 1 AND result = 2
) AS all_wins
GROUP BY player_id
ORDER BY win_count DESC;
为什么这个方案更优?

相比你之前尝试的ORDER BY battles.player2,这个方案的优势在于:

  • 逻辑更清晰:通过窗口函数的分区功能,直接明确地为每对玩家分组并筛选最早记录,不需要额外的去重操作
  • 性能更高效:窗口函数的分区排序在大数据量下比多次ORDER BY后去重的性能更好,数据库可以更高效地处理分组逻辑
  • 扩展性强:如果后续需要调整对战结果的判定规则(比如增加平局处理、不同result值的定义),只需要修改子查询里的条件即可

如果你的业务里不存在player2获胜的场景,只需要去掉UNION ALL后面的部分即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:42:19