mysql中的用户按他们的分数排名

Posted

技术标签:

【中文标题】mysql中的用户按他们的分数排名【英文标题】:Rank users in mysql by their points 【发布时间】:2016-01-06 16:29:49 【问题描述】:

我正在尝试按照我之前计算的分数对我的学生进行排名 但问题是如果学生有相同的分数,他们都应该在同一个等级 例如

学生 1 满分 学生2满分

他们都必须排名为 1;

这是我的数据库的示例

我正在尝试做的查询是(仅用于选择然后我可以将值插入我的列)

 SELECT  a.points
        count(b.points)+1 as rank
FROM  examresults a left join examresults b on a.points>b.points
group by  a.points;

为了更清楚而编辑:

学生1分80 学生2分77.5 学生3分77.5 学生4分77

他们的等级应该是这样的

学生1排名1 学生2排名2 学生3排名2 学生4排名3

我当前的查询返回一个类似

的值

因为它缺少第三级。 (因为第二个等级有 2 个值)

【问题讨论】:

假设学生 A 和 B 有 20 分,C 有 18 分,您希望 A 和 B 排名 1,C 排名 2 或 3? A 和 B 排名 1 和 C 排名 2 【参考方案1】:

这只是使用变量修复 Gordon 解决方案。问题是您的排名功能不是排名应该工作的方式。 (学生 4 应该是 4 级)

SQL Fiddle Demo 您可以添加更多学生来改进测试。

select er.*,
       (@rank := if(@points = points, 
                    @rank, 
                    if(@points := points,    
                       @rank + 1, 
                       @rank + 1                       
                      )
                   )                  
       ) as ranking
from students er cross join
     (select @rank := 0, @points := -1) params
order by points desc;

输出

| id | points | ranking |
|----|--------|---------|
|  1 |     80 |       1 |
|  2 |     78 |       2 |
|  3 |     78 |       2 |
|  4 |     77 |       3 |
|  5 |     66 |       4 |
|  6 |     66 |       4 |
|  7 |     66 |       4 |
|  8 |     15 |       5 |

【讨论】:

这是一个dense_rank(),而不是一个排名。因此,它将返回 1、1、1、2,而不是 1、1、1、4。 . .但这似乎是 OP 所要求的。 您能否对您的查询进行一些修改,如果同一学生的数据有多行,那么我们需要根据该用户所有点的sum 计算排名。查看此链接获取数据sqlfiddle.com/#!9/95dff ?谢谢 @Sachin,对不起,我不明白,您是否与 OP 合作并需要新的要求?我没有看到 OP 说一个学生可以有超过一分的结果 @Sachin 如果您需要帮助解决类似但不同的问题,只需创建一个新问题,我会在那里提供帮助,请告诉我。但我无法更改此答案,因为与此问题有关。 @JuanCarlosOropeza,没问题。我刚刚创建了一个新问题,请你看看这个.. ***.com/questions/34682333/…【参考方案2】:

您需要一个真实的排名,该排名由 ANSI 标准 rank() 函数计算得出。您可以使用以下逻辑在 mysql 中实现:

select er.*,
       (select 1 + count(*)
        from examresults er2
        where er2.points > er.points
       ) as ranking
from exampleresults er;

对于较大的表,您可以使用变量来执行此操作,但比较尴尬:

select er.*,
       (@rank := if(@rn := @rn + 1              -- increment row number
                    if(@points = points, @rank, -- do not increment rank
                       if(@points := points,    -- set @points
                          @rn, @rn              -- otherwise use row number
                         )
                       )
                   )
       ) as ranking
from examresults er cross join
     (select @rn := 0, @rank := 0, @points := -1) params
order by points desc;

【讨论】:

【参考方案3】:

这个查询实现你想要的:

SELECT  student_id , points, (select count(distinct(points))+1 as rank 
from examresults internal 
where internal.points > external.points order by points)
FROM  examresults external 
group by  student_id

【讨论】:

抱歉还是不行。 SELECT 列表的表达式 #2 不在 GROUP BY 子句中,并且包含在功能上不依赖于 GROUP BY 子句中的列的非聚合列“onlineform_1.external.points”;这与 sql_mode=only_full_group_by 不兼容,如果我逐个删除组,那么它会完全搞砸

以上是关于mysql中的用户按他们的分数排名的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 基于得分和时间的排名

从使用 PHP 的 MySQL 数据库到 iPhone 的分数列表中获取排名

按排名按顺序设置字段,但在另一个字段的组中

LeetCode 中的 SQL 语法错误排名分数

当他们的分数相等时,如何将排名分配给他们共享最高排名的学生?

LeetCode-178-分数排名(面试必备)