0

我有一个包含用户和积分的数据库(实际上是一个百分比,但这没关系)。得分最高的用户排在第一位,第二位排在第二位...

$searchedUserID如果我做这样的想法,我可以获得a的排名:

SELECT `user_id`, `points` FROM `usertable` ORDER BY `points` DESC
/** This function returns the rank of a user. The rank nr. 1 is the best.
 *  It is possible that some users share a rank.
 *
 * @param int $searchedUserID the ID of the user whose rank you would like to 
 *                            know
 *
 * @return int rank
 */
function getUserRank($searchedUserID)
{
    $userArray = getAllUsersOrderedByPoints();
    $rank       = 0;
    $lastPoints = -1; // Never happens
    foreach ( $userArray as $user) {
        if ($user['point'] != $lastPoints)  $rank++;
        if ($user['user_id'] == $searchedUserID) break;
    }
    return $rank;
}

没有更直接的方法来使用(My)SQL 获得这个吗?如果不是:可以改进 PHP 部分吗?

(编辑:我可以将 PHP 计算的排名直接存储在数据库中……但这意味着我必须进行很多更新。)

edit2:也许GROUP BY可以使用?就像是:

SELECT `user_id`, `points` FROM `usertable` GROUP BY `points` ORDER BY `points` DESC

这个查询的问题是我没有得到搜索到的 user_id。有必要发送第二个查询:

SELECT `user_id` FROM `usertable` WHERE `points` = $pointsOfTheUser
4

2 回答 2

0

你问:

没有更直接的方法来使用(My)SQL 获得这个吗?

是的。在 SQL:2003 中,您可以使用 DENSE_RANK() 窗口函数。在 MySQL 中,您可以模拟这一点,因为某个记录的(密集)排名只是不同更好分数的计数 + 1:

   SELECT u.user_id,
          u.points,
          1 + COUNT(DISTINCT others.points) AS `dense_rank`
     FROM users u
LEFT JOIN users others
          ON u.points < others.points  -- Which other users have more points?
    WHERE user_id = ?
 GROUP BY 1, 2;
于 2012-01-18T15:03:35.140 回答
0

也许与 group by 和 sort 进行内部连接可以解决问题?

SELECT * FROM 
INNER JOIN
  (
    SELECT user_id AS uid, max(points) AS score 
    FROM usertable GROUP BY user_id
  )
AS ds ON usertable.user_id = ds.uid AND usertable.points = ds.score
ORDER BY score DESC

只是在纸上思考(像素)..这不会按从最高点到最低点的顺序为您提供列表,每个用户都有独特的记录...或者您是否希望将这些排序在您可以将领带澄清为单个排名中的“位置”?

于 2012-01-18T15:16:43.617 回答