2011-10-09 59 views
0

我有一個包含用戶和積分的數據庫(實際上它是一個百分比,但這並不重要)。用戶(S)與點的最高的數字是第一級,第二個第二級...使用積分計算排名

如果我這樣做somethink這樣我能得到一個$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直接在數據庫中計算的排名......但是這將意味着我不得不做出相當多的更新。)

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 
+1

一般來說,它比使用mySQL更快地對PHP進行排序。如果你在最後一個查詢中使用或不使用'ORDER BY'對查詢執行'EXPLAIN',你會明白我的意思。這是數據集變大時要考慮的事情。只是我的2cp。 –

+3

我喜歡'//不會發生'評論;) – sjngm

+0

@sjngm:這對了解最佳排名是否應該是重要的。如果我使用負排名,最高的數字是-1,返回的排名是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; 
0

也許內參加由和排序會做的招?

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 

只是想在紙上(像素)..不會說給你名單,以便從最高點到最低的每用戶一個唯一的記錄...或者你希望有這些分類,你可以在排名中將一條領帶作爲單一的「地點」來澄清?