Привет, кодеры по всему миру,
Я работаю над проектом, в котором пользователи могут делать определенные вещи и получать очки за это. Чтобы упростить этот вопрос, скажем, мы получили 2 пользователя и точки таблицы.
-- table user -- table points +---------------+ +-----------------------------+ | id | name | | id | points | user_id | +---------------+ +-----------------------------+ | 1 Tim | | 1 5 1 | | 2 Tom | | 2 10 1 | | 3 Marc | | 3 5 1 | | 4 Tina | | 4 12 2 | | 5 Lutz | | 5 2 2 | +---------------+ | 6 7 1 | | 7 40 3 | | 8 100 1 | +-----------------------------+
Теперь, чтобы получить полный список рекордов, я использую следующий запрос
SELECT u.*, SUM( p.points ) AS sum_points FROM user u LEFT JOIN points p ON p.user_id = u.id GROUP BY u.id ORDER BY sum_points DESC
в результате получается прекрасный рекордер со всеми пользователями от первого до последнего
+------------------------------+ | id | name | sum_points | +------------------------------+ | 1 Tim 127 | | 3 Marc 40 | | 2 Tom 14 | | 4 Tina 0 | | 5 Lutz 0 | +------------------------------+
Вернемся к самому вопросу. В профиле одного пользователя я хотел бы показать его рейтинг в списке рекордов.
Можно ли это сделать, используя один запрос, просто показывающий, что, например, Tom (id = 2) занимает место 3?
Большое спасибо 🙂
Идея состоит в том, чтобы спросить: «Сколько игроков занимает выше @this_user»:
select count(*) + 1 from ( /* list of all users */ SELECT SUM( p.points ) AS sum_points FROM user u LEFT JOIN points p ON p.user_id = u.id GROUP BY u.id ) x /* just count the ones with higher sum_points */ where sum_points > (select sum(points) from points where user_id = @this_user)
Отредактировано для создания результата 1 вместо 0-основанного
SELECT q.*, @r := @r + 1 AS rank FROM ( SELECT @r := 0 ) vars, ( SELECT u.*, SUM(p.points) AS sum_points FROM user u LEFT JOIN points p ON p.user_id = u.id GROUP BY u.id ORDER BY sum_points DESC ) q