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

PHP MySQL如何查询自身分数上下各2名的排行榜记录

实现游戏排行榜自身分数上下各2名的查询方案

这个需求完全可行,以下是具体实现方法:

一、MySQL 查询实现

假设你的排行榜表名为leaderboard,包含字段player_id(玩家唯一标识)、player_name(玩家名称)、score(分数),分数越高排名越靠前。

1. 核心思路

先计算出自身的排名,再筛选出排名在「自身排名-2」到「自身排名+2」之间的记录。需要注意同分场景的排名逻辑,这里提供两种常见排名方式:

方式1:严格排名(同分玩家占用不同排名)

-- 先获取自身排名
SELECT COUNT(*) + 1 AS my_rank
FROM leaderboard
WHERE score > (SELECT score FROM leaderboard WHERE player_id = '你的玩家ID');

-- 查询上下各2名的记录
WITH ranked_players AS (
    SELECT 
        player_name,
        score,
        RANK() OVER (ORDER BY score DESC) AS player_rank
    FROM leaderboard
)
SELECT player_rank, player_name, score
FROM ranked_players
WHERE player_rank BETWEEN (
    SELECT COUNT(*) + 1 FROM leaderboard WHERE score > (SELECT score FROM leaderboard WHERE player_id = '你的玩家ID')
) - 2 
AND (
    SELECT COUNT(*) + 1 FROM leaderboard WHERE score > (SELECT score FROM leaderboard WHERE player_id = '你的玩家ID')
) + 2
ORDER BY player_rank ASC;

方式2:稠密排名(同分玩家共享同一排名)

只需将上述代码中的RANK()替换为DENSE_RANK()即可,适合需要同分同排名的场景。

兼容低版本MySQL(<8.0,无窗口函数)

用变量计算排名:

-- 查询上下各2名的记录
SELECT player_rank, player_name, score
FROM (
    SELECT 
        @rank := @rank + 1 AS player_rank,
        player_name,
        score
    FROM leaderboard, (SELECT @rank := 0) AS r
    ORDER BY score DESC
) AS ranked
WHERE player_rank BETWEEN (
    SELECT COUNT(*) + 1 FROM leaderboard WHERE score > (SELECT score FROM leaderboard WHERE player_id = '你的玩家ID')
) - 2 
AND (
    SELECT COUNT(*) + 1 FROM leaderboard WHERE score > (SELECT score FROM leaderboard WHERE player_id = '你的玩家ID')
) + 2;

二、PHP 代码处理

以下是基于PDO的实现示例,确保查询逻辑与数据库交互的完整性:

<?php
// 数据库连接参数
$host = 'localhost';
$dbname = '你的数据库名';
$username = '你的数据库账号';
$password = '你的数据库密码';

try {
    // 初始化PDO连接
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // 当前玩家ID
    $playerId = '你的玩家ID';

    // 获取自身排名
    $rankStmt = $pdo->prepare("
        SELECT COUNT(*) + 1 AS my_rank 
        FROM leaderboard 
        WHERE score > (SELECT score FROM leaderboard WHERE player_id = :playerId)
    ");
    $rankStmt->bindParam(':playerId', $playerId, PDO::PARAM_STR);
    $rankStmt->execute();
    $myRank = $rankStmt->fetch(PDO::FETCH_ASSOC)['my_rank'];

    // 计算查询范围(避免排名小于1)
    $minRank = max(1, $myRank - 2);
    $maxRank = $myRank + 2;

    // 查询目标记录
    $stmt = $pdo->prepare("
        WITH ranked_players AS (
            SELECT 
                player_name,
                score,
                RANK() OVER (ORDER BY score DESC) AS player_rank
            FROM leaderboard
        )
        SELECT player_rank, player_name, score 
        FROM ranked_players 
        WHERE player_rank BETWEEN :minRank AND :maxRank
        ORDER BY player_rank ASC
    ");
    $stmt->bindParam(':minRank', $minRank, PDO::PARAM_INT);
    $stmt->bindParam(':maxRank', $maxRank, PDO::PARAM_INT);
    $stmt->execute();

    // 输出结果
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    foreach ($results as $row) {
        echo "{$row['player_rank']}. {$row['player_name']} {$row['score']}\n";
    }

} catch(PDOException $e) {
    echo "数据库错误:" . $e->getMessage();
}
$pdo = null;
?>

关键注意点

  • 当自身排名为前2名时,minRank会被强制设为1,避免出现无效的负排名;
  • 若自身排名为倒数2名,maxRank会自动匹配表中最大排名,不会返回空结果;
  • 根据业务需求选择合适的排名算法(严格/稠密),确保排行榜逻辑符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:10:29