2009-08-18 12 views
10

Mam tabeli mysql jak poniżej:MySQL, Get użytkowników rangi

id  name  points 
1  john  4635 
3  tom  7364 
4  bob  234 
6  harry 9857 

Zasadniczo chcę, aby uzyskać indywidualną pozycję użytkownika bez zaznaczania wszystkich użytkowników. Chcę tylko wybrać pojedynczego użytkownika według id i uzyskać ranking użytkowników, który jest określony przez liczbę punktów, które mają.

Na przykład wrócić tom w randze 2 Wybór przez ID 3.

Cheers

Eef

Odpowiedz

18
SELECT uo.*, 
     (
     SELECT COUNT(*) 
     FROM users ui 
     WHERE (ui.points, ui.id) >= (uo.points, uo.id) 
     ) AS rank 
FROM users uo 
WHERE id = @id 

Ranking Gęsty:

SELECT uo.*, 
     (
     SELECT COUNT(DISTINCT ui.points) 
     FROM users ui 
     WHERE ui.points >= uo.points 
     ) AS rank 
FROM users uo 
WHERE id = @id 
+0

Cheers mate działa idealnie – RailsSon

+0

kocham go. Trochę strojenia i pasuje do moich potrzeb. Tnx do dzielenia się! –

+0

Drobny problem: jeśli istnieją więzy, to zwróci najwyższą pozycję, a nie najniższą. Jeśli chcesz najniższego, zmień warunek na '>', a wartość na 'COUNT (*) + 1'. – Barmar

2

Rozwiązanie przez @ Quassnoi zawiedzie w przypadku więzi. Oto rozwiązanie, które będzie działać w przypadku powiązań:

SELECT *, 
IF (@score=ui.points, @rank:[email protected], @rank:[email protected]+1) rank, 
@score:=ui.points score 
FROM users ui, 
(SELECT @score:=0, @rank:=0) r 
ORDER BY points DESC 
+0

Uwaga: ranga będzie wynosić 0, jeśli pierwsze miejsce ma wynik 0. Dodatkowo, w przypadku remisów, ranga jest zwiększana, a nie pomijana, np. 10 - 1, 9 - 2, 9 - 2, 6 - 3. Ponadto pobieranie wierszy powinno znajdować się w podkwerendie, ponieważ kolejność jest stosowana po rankingach. – Sean

0
SET @rownum := 0; 
SELECT rank, score FROM (SELECT @rownum := @rownum +1 AS rank, `score` ,`user_id` 
FROM leaderboard 
ORDER BY `score` DESC , `updated_timestamp`) as result WHERE `user_id`=$user_id 
LIMIT 1 
Powiązane problemy