用积分计算等级

时间:2011-10-09 14:49:38

标签: php mysql rank

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

如果我做了这样的事情,我可以得到$searchedUserID的等级:

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计算出的等级存储在数据库中......但这意味着我必须进行大量的UPDATE。)

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

2 个答案:

答案 0 :(得分:0)

你问:

  

是不是有更直接的方法来获取(我的)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;

答案 1 :(得分: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

只考虑纸张(像素)..不会按照从最高点到最低点的顺序为您提供每个用户的唯一记录的列表...或者您是否希望将这些排序放在可以澄清领带的位置作为排名中的一个“地方”?