首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用查找在一组用户排名的基础上的分数?

如何使用查找在一组用户排名的基础上的分数?
EN

Stack Overflow用户
提问于 2018-08-08 09:16:34
回答 3查看 69关注 0票数 0

我有这样的疑问,

代码语言:javascript
复制
SELECT * FROM users ORDER BY score

结果是这样的。

代码语言:javascript
复制
Array
(
    [0] => stdClass Object
        (
            [userid] => 3
            [user] => John Doe
            [score] => 50
        )

    [1] => stdClass Object
        (
            [userid] => 1
            [user] => Mae Smith
            [score] => 38
        )

    [2] => stdClass Object
        (
            [userid] => 2
            [user] => Mark Sam
            [score] => 26
        )
)

但是,我想使用find_in_set查询添加一个级别。结果可能是这样的。这样,当用户登录到他们的帐户时,就可以查看他们的排名。

代码语言:javascript
复制
Array
(
    [0] => stdClass Object
        (
            [userid] => 3
            [user] => John Doe
            [score] => 50
            [rank] => 1
        )

    [1] => stdClass Object
        (
            [userid] => 1
            [user] => Mae Smith
            [score] => 38
            [rank] => 2
        )

    [2] => stdClass Object
        (
            [userid] => 2
            [user] => Mark Sam
            [score] => 26
            [rank] => 3
        )
)

我试过这个。

代码语言:javascript
复制
$listOfUser = array();
foreach($users as $user) {
   $listOfUser[] = $user->userid;
}

并使用了另一个查询

代码语言:javascript
复制
$userid = 2 // => id of loggedin user
SELECT *, find_in_set($userid, $listOfUser) as rank FROM users where userid=$userid ORDER BY score

所以,我得到了这个结果

代码语言:javascript
复制
Array
(

    [1] => stdClass Object
        (
            [userid] => 2
            [user] => Mark Sam
            [score] => 26
            [rank] => 3
        )
)

这在某种程度上是正确的。但是,是否有另一种方法只使用一个SQL查询而不使用foreach循环来查询结果呢?

就像这样。

代码语言:javascript
复制
$userid = 2 // => id of loggedin user
SELECT *, find_in_set($userid, (SELECT * FROM users ORDER BY score)) as rank FROM users where userid=$userid ORDER BY score

但是我得到了一个错误Subquery returns more than 1 row

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-08-08 09:25:01

如果您不坚持使用find_in_set,则可以通过简单的联接获得结果。您需要用户列表(p),对于每个用户,有多少用户的得分比他(她)(c)要好:

代码语言:javascript
复制
SELECT p.userid, COUNT(c.userid) AS rank
FROM users AS p
LEFT JOIN users AS c ON c.score > p.score
GROUP BY p.userid

即使添加了其他条件,比如WHERE p.userid = 123,这也是可行的。如果更多的用户拥有相同的分数,那么排名就会像0,1,2,2,2,5,6一样。

票数 4
EN

Stack Overflow用户

发布于 2018-08-08 09:28:13

在查询中,可以添加计数器,如下所示:

代码语言:javascript
复制
set @n:=0; 
SELECT @i := @i + 1 AS rank, * FROM users ORDER BY score
票数 0
EN

Stack Overflow用户

发布于 2018-08-08 09:29:48

这里的排名相对于所有用户的分数分布。我相信你应该尝试一些最初提出的in this answer

代码语言:javascript
复制
SELECT users.*, 
   @rownum := @rownum + 1 as rank
FROM users
CROSS JOIN (select @rownum := 0) r
ORDER BY score DESC

它所做的基本上是按分数对所有用户进行排序,并为每个用户分配一个递增值“排名”。所以最好的得分手的排名是1,第二得分手的排名是2等等。

请记住,这个解决方案是“不公平的”-每个用户将有一个不同等级的,即使所有用户的都有相同的分数。如果你试着像他们在体育比赛中那样对用户进行排名(如果两个顶级选手的得分相同,他们都是第一名,其次是第三名,而不是第二名),那么你应该想出一个不同的解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51742912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档