2012-01-24 1 views
3

Есть несколько ранговых сообщений, но мне еще предстоит увидеть, когда речь идет о том, когда результаты разбиты на страницы и когда критерии ранжирования (в данном случае: точки) равны предыдущему пользователю , Я пробовал несколько из ранее существовавших примеров, но никто не работал.Получить рейтинг пользователя на основе суммы с разбивкой по страницам

У меня есть таблица, называемая «пользователями», с столбцом «id». У меня также есть таблица под названием «points» с столбцами «user_id» и «amount».

мне нужно:

1.) Пользователи с дубликата суммой баллов, чтобы иметь тот же ранг

Очки Таблица

user_id  amount 
    1   10 
    2   20 
    1   5 
    3   20 
    3   -5 
    4   5 

место должно быть

rank  user_id total 
1   2  20 
2   1  15 
2   3  15 
3   4  5 

2.) Необходимо поддерживать рейтинг с одного ранга ge к другому, поэтому ранжирование должно быть собрано в запросе, а не в результате PHP.

3.) Отображать ВСЕ пользователей не только с строками в таблице точек, так как у некоторых пользователей есть 0 очков, и я хочу их отображать последними.

Сейчас я просто перечисляю пользователей по порядку своих очков, но их ранг не собран, потому что он не работает.

$getfanspoints = mysql_query("SELECT DISTINCT id, 
(SELECT SUM(amount) AS points FROM points WHERE points.user_id = users.id) AS points 
FROM users 
ORDER BY points DESC LIMIT $offset, $fans_limit", $conn); 

Я читал эти решения, и никто из них не работал.

[Блог Роланда] [1]

[Как получить ранг на основе СГМ] [2]

[MySQL, получить пользователи ранга] [3]

[Как получить звание используя mysql query] [4]

и несколько других, чью ссылку я не могу найти прямо сейчас.

Любые предложения?

[EDIT]

Я использовал нижний ответ ypercube в.

+0

Просто примечание: если вы показываете ряды больше, чем вы их меняете, стоит подумать о денормализации ваших таблиц и сохранении суммы очков для каждого пользователя в таблице пользователей. Обновляйте его только тогда, когда пользователь получает несколько очков, вместо того, чтобы пересчитывать его для каждого рендеринга страницы. – bububaba

+0

Я думаю, что это будет сложно сделать с моей ситуацией, так как пользователи зарабатывают и быстро теряют очки, но точки также являются «в очереди», между задержкой и очками есть задержка, и когда они могут реально использовать свои очки для вещей , Также каждая точка привязана к определенному действию. Таблица точек также включает столбцы page_id, module_id, post_id, group_id, item_id, other_users. Они зарабатывают и теряют очки за разные действия, и журнал их отображается в их профиле и на панели пользователя. Трудно объяснить, но я не чувствую, что это сработает. – bowlerae

ответ

1
SELECT COUNT(*) AS rank 
    , t.user_id 
    , t.total 
FROM 
     (SELECT user_id 
      , SUM(amount) AS total 
     FROM  points 
     GROUP BY user_id 
    ) AS t 
    JOIN 
     (SELECT DISTINCT 
       SUM(amount) AS total 
     FROM  points 
     GROUP BY user_id 
    ) AS dt 
    ON 
     t.total <= dt.total 
GROUP BY t.user_id 
ORDER BY rank 
     , user_id 

Но выше, может быть очень медленно, с большим столом и баллами часто.Это может быть действительно лучше иметь только это и вычислить ранги в коде приложения:

SELECT users.id AS user_id 
    , SUM(amount) AS total 
FROM  
     users 
    LEFT JOIN 
     points 
    ON points.user_id = users.id 
GROUP BY users.id 
ORDER BY total DESC 
     , user_id 

Это будет работать, тоже (отредактирован, чтобы работать с users столом и с OFFSET):

SELECT * 
FROM 
    (SELECT 
      @rank := @rank + (@t <> total) AS rank 
     , user_id 
     , @t := total AS total 
    FROM 
     (SELECT users.id AS user_id 
       , COALESCE(SUM(amount),0) AS total 
      FROM users 
      LEFT JOIN points 
       ON users.id = points.user_id 
      GROUP BY users.id 
     ) AS o 
     CROSS JOIN 
     (SELECT @rank := 0, @t := -999999 
     ) AS dummy 
    ORDER BY total DESC 
      , user_id 
) tmp 
LIMIT x OFFSET y 
+0

Ни одно из решений не работает, сообщение об ошибке просто не возвращает 0 результатов. Почему он должен выбирать САМ (количество) AS total FROM users, а не из точек? – bowlerae

+0

Да, это должно быть от «очков». –

+0

он не работал :(но я думаю, что мог бы просто получить его. Проверьте выше. – bowlerae