按分数对 mysql 中的用户进行排名
Rank users in mysql by their points
我正在尝试根据我之前计算的分数对我的学生进行排名
但问题是如果学生的分数相同,他们应该处于同一等级
例如
学生1满分
学生 2 获得满分
它们都必须排名为 1;
这是我的数据库的示例
我正在尝试执行的查询是(仅针对 select 然后我可以将值插入到我的列中)
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
我当前的查询 returns 一个类似
的值
因为少了三阶。 (因为第二个等级有 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;
这个查询实现了你想要的:
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
这只是使用变量修复 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 |
我正在尝试根据我之前计算的分数对我的学生进行排名 但问题是如果学生的分数相同,他们应该处于同一等级 例如
学生1满分 学生 2 获得满分
它们都必须排名为 1;
我正在尝试执行的查询是(仅针对 select 然后我可以将值插入到我的列中)
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
我当前的查询 returns 一个类似
的值因为少了三阶。 (因为第二个等级有 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;
这个查询实现了你想要的:
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
这只是使用变量修复 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 |