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

如何获取mysqli多查询结果及用户在排行榜的排名位置

问题分析与解决方案

你的代码主要存在两个核心问题:

  1. multi_query与预处理参数绑定不兼容:multi_query执行后返回的是布尔值(仅表示查询是否启动成功),而非mysqli预处理语句对象,因此后续调用bind_param必然报错。
  2. SQL语句语法错误:代码末尾多了冗余的";"",导致查询解析失败。

下面给出两种正确的实现方式,优先推荐第一种(安全且简洁):

方案一:单查询+预处理参数绑定(推荐)

将排名变量的初始化逻辑合并到主查询中,通过CROSS JOIN初始化变量,这样可以用预处理语句安全绑定参数,彻底避免SQL注入风险:

// 构造单查询SQL,内部完成排名变量初始化
$sql = "SELECT RANK FROM
        (
            SELECT @rank:=@rank+1 AS 'RANK', user_id FROM
            (
                SELECT score, user_id
                FROM `fishing_contest` 
                GROUP BY user_id 
                ORDER BY score DESC
            ) as t1
            CROSS JOIN (SELECT @rank:=0) AS init_rank
        ) as t2
        WHERE user_id = ?";

// 初始化预处理语句
$stmt = $mysqli->prepare($sql);
// 绑定用户ID参数(i表示整数类型)
$stmt->bind_param("i", $_SESSION['id']);
// 执行查询
$stmt->execute();
// 获取结果集
$data = $stmt->get_result();
// 提取用户排名数据
$userContest = $data->fetch_assoc();

// 结果使用示例
if ($userContest) {
    echo "当前排名:" . $userContest['RANK'];
} else {
    echo "未查询到你的参赛记录";
}

方案二:使用multi_query(不推荐,存在注入风险)

如果一定要用多查询方式,需要跳过第一个SET语句的结果,且无法使用参数绑定(需手动确保用户ID的安全性):

// 强制转换用户ID为整数,避免SQL注入风险
$safeUserId = (int)$_SESSION['id'];

// 构造多查询SQL
$sql = "SET @rank=0;
        SELECT RANK FROM
        (
            SELECT @rank:=@rank+1 AS 'RANK', user_id FROM
            (
                SELECT score, user_id
                FROM `fishing_contest` 
                GROUP BY user_id 
                ORDER BY score DESC
            ) as t1
        ) as t2
        WHERE user_id = $safeUserId";

// 执行多查询
if ($mysqli->multi_query($sql)) {
    // 跳过第一个SET语句的结果集
    $mysqli->next_result();
    // 获取第二个查询的结果
    if ($result = $mysqli->store_result()) {
        $userContest = $result->fetch_assoc();
        $result->free();
    }
}

// 结果使用示例
if ($userContest) {
    echo "当前排名:" . $userContest['RANK'];
} else {
    echo "未查询到你的参赛记录";
}

关键说明

  • 预处理语句(prepare/bind_param)仅支持单查询,无法与multi_query配合使用。
  • 方案一的CROSS JOIN初始化变量方式,是MySQL中实现排名查询的标准写法,既安全又高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:45:48