如何使用 PHP 函数更有效地获取 table 中多列的排名

how to use PHP function to get ranks for multiple columns in a table more efficent

我正在尝试为 table 中的每个统计数据 "column" 的用户获得单一排名。我正在尝试更有效地做到这一点,因为我知道你可以。

所以我有一个名为 userstats 的 table。其中 table 我有 3 列 user_id、stat_1、stat_2 和 stat_3。我希望我能够获得相关 user_id 的每个统计数据的排名。使用下面我当前的代码,我将不得不复制代码 3x 并更改列名以获得我的结果。请看下面的例子。谢谢!

这就是我目前获得用户排名的方式

$rankstat1 = getUserRank($userid);

<code>
function getUserRank($userid){

   $sql     =  "SELECT * FROM ".DB_USERSTATS." ORDER BY stat_1 DESC";
   $result =  mysql_query($sql);
   $rows  =  '';

   $data = array();
   if (!empty($result))
        $rows      =  mysql_num_rows($result);
   else
        $rows      =  '';

    if (!empty($rows)){
        while ($rows = mysql_fetch_assoc($result)){
                $data[]   = $rows;
        }
    }

   $rank = 1;
   foreach($data as $item){
       if ($item['user_id'] == $userid){
           return $rank;
       }
       ++$rank;
   }
   return 1;
}
</code>

我相信有一种方法可以让我得到我需要的东西,但我无法让它工作。

$rankstat1 = getUserRank($userid, 'stat_1'); $rankstat2 = getUserRank($userid, 'stat_2'); $rankstat3 = getUserRank($userid, 'stat_3');

$sql     =  "SELECT user_id, stat_1, stat_2, stat_3 FROM ".DB_USERSTATS." ORDER BY stat_1 DESC";

此外,除非有理由需要所有用户的结果,否则请使用 WHERE 子句限制您的查询,以便您只获得实际需要的结果。

假设您将 sql 查询限制为仅一个用户,这将获取该用户的统计信息。

foreach($data as $item){
   $stat_1 = $item['stat_1'];
   $stat_2 = $item['stat_2'];
   $stat_3 = $item['stat_3'];
}

如果您通过 sql 查询获得多个用户的统计信息,请考虑将您的 $data 数组传回调用函数并循环遍历该数组以将用户统计信息与特定用户 ID 相匹配。

您可以使用一次查询获得所有统计排名,而无需执行所有 PHP 循环和检查。

我在这个例子中使用了PDO,因为$userid变量的值需要在查询中使用,并且已弃用的mysql数据库扩展不支持prepared statements,这应该是用于降低 SQL 注射的风险。

该函数可以调整为使用与 mysqli 相同的查询,如果您必须使用它,甚至 mysql

function getUserRanks($userid, $pdo) {
    $sql = "SELECT 
        COUNT(DISTINCT s1.user_id) + 1 AS stat_1_rank, 
        COUNT(DISTINCT s2.user_id) + 1 AS stat_2_rank, 
        COUNT(DISTINCT s3.user_id) + 1 AS stat_3_rank
    FROM user_stats f
        LEFT JOIN user_stats s1 ON f.stat_1 < s1.stat_1
        LEFT JOIN user_stats s2 ON f.stat_2 < s2.stat_2
        LEFT JOIN user_stats s3 ON f.stat_3 < s3.stat_3
    WHERE f.user_id = ?"

    $stmt = $pdo->prepare($sql);
    $stmt->bindValue(1, $userid);
    $stmt->execute();
    $ranks = $stmt->fetchObject();
    return $ranks;
}

这应该 return 一个对象,其属性包含给定用户的每个统计数据的排名。使用此函数的示例:

$pdo = new PDO($dsn, $user, $pw);
$ranks = getUserRanks(3, $pdo);      // get the stat ranks for user 3
echo $ranks->stat_2_rank;            // show user 3's rank for stat 2