简体   繁体   中英

How can we rank by sum of score on mySQL and PHP

Table: tbluser

| id | fb_uid | fb_full_name |
 ----------------------------
| 1  |  101   |   user_101   |
| 2  |  102   |   user_102   |
| 3  |  103   |   user_103   |
| 4  |  104   |   user_104   |

Table: userscore

| id | user_id | cat_id | score |
  -------------------------------
 | 1  |    101  |    1   |  100  |
 | 2  |    102  |    1   |  200  |
 | 3  |    101  |    2   |  300  |
 | 4  |    104  |    1   |  450  |
 | 5  |    103  |    1   |  500  |
  -------------------------------

MySQL & PHP: How can we result as:

| Rank | Name          | score |
 ------------------------------
|  1   | user_103      |  500  |
|  2   | user_104      |  450  |
|  3   | user_101      |  400  |
|  4   | user_102      |  200  |

Try this:

SELECT 
    @rank := @rank + 1 AS Rank,
    u.fb_full_name,
    SUM(us.score) AS new_score
FROM userscore us INNER JOIN tbluser u ON us.user_id = u.id
    CROSS JOIN (SELECT @rank := 0) param
ORDER BY new_score DESC

You should try this:

SELECT @r := 0;    

SELECT @r := @r + 1 AS Rank,u.fb_full_name AS Name,SUM(us.score) AS Score
FROM userscore as us 
INNER JOIN tbluser as u ON us.user_id = u.fb_uid 
ORDER BY new_score DESC;

This is pure SQL.

select count(us2.user_id)+1 rank, u.fb_full_name, us.score
from tbluser u
join (
    select user_id, sum(score) score
    from userscore
    group by user_id
) us on us.user_id = u.fb_uid
left join (
    select user_id, sum(score) score
    from userscore
    group by user_id
) us2 on us2.score > us.score
group by u.fb_full_name, us.score
order by rank, us.user_id

fiddle1 fiddle2

If two players have the same score they get the same rank and the next rank will be skipped eg

1 user1 500
2 user2 400
2 user3 400
4 user4 300

But it's much easier to rank the users in PHP with

select u.fb_full_name, sum(us.score) score
from tbluser u
join userscore us on us.user_id = u.fb_uid
group by u.fb_full_name
order by score desc, u.id

and something like

$users = array();
$i = 0;
while ($row = $result->fetchAssoc()) {
    $row['rank'] = ++$i;
    $users[] = $row;
}

or

$users = array();
$lastScore = null;
$lastRank = 1;
$rank = 0;
while ($row = $result->fetchAssoc()) {
    ++$rank;
    if ($row[score] !== $lastScore) {
        $lastRank = $rank;
    }
    $row[rank] = $lastRank;
    $users[] = $row;
}

You have to use JOIN in your query as below :

SELECT tbluser.fb_full_name, SUM(userscore.score) AS userscore FROM tbluser
JOIN userscore ON tbluser.fb_uid = userscore.user_id
GROUP BY tbluser.fb_uid
ORDER BY userscore DESC;

See the implementation of your example over here.

http://sqlfiddle.com/#!9/7482f/9

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM