我的问题是,
我在mysql中有一个表
哪些列是
id Student score
1 A 55
2 B 86
3 C 65
4 D 23
5 E 84
6 F 45
7 G 80我想根据分数找出整个班级中任何学生的排名,得分较高的学生和得分较低的学生的排名。例如,如果我正在搜索学生E
则输出应为
id User score rank_in_classs
2 B 86 1
5 E 84 2
7 G 80 3另一个例子可以是,如果我正在寻找学生A
id User score rank_in_classs
3 c 65 4
1 A 55 5
6 F 45 6如何使用mysql查询找到它。
谢谢
发布于 2014-10-01 11:37:58
查询
SELECT id, Student, score,
FIND_IN_SET( score, (
SELECT GROUP_CONCAT( score
ORDER BY score DESC )
FROM tbl )
) AS rank_in_class
FROM tbl
ORDER BY rank_in_class
LIMIT 3;DEMO
发布于 2014-10-02 14:30:11
使用Ullas提出的基于FIND_IN_SET()的解决方案,您可以这样定位特定的学生+/- 1排名:
set @this_rank := (
SELECT
FIND_IN_SET( score, (
SELECT GROUP_CONCAT( score
ORDER BY score DESC )
FROM tbl
)
) AS rank_in_class
FROM tbl
where student = 'A'
);
select
*
from (
SELECT
id
, Student
, score
, FIND_IN_SET( score, (
SELECT GROUP_CONCAT( score
ORDER BY score DESC )
FROM tbl
)
) AS rank_in_class
FROM tbl
) ric
where rank_in_class between @this_rank-1 AND @this_rank+1
ORDER BY rank_in_class
LIMIT 3;注意:如果你在表中存储了排名值,那么这就不会那么麻烦了,而且性能会更好。
发布于 2014-10-03 08:40:04
最好的方法可能是混合使用两个查询和少量PHP。
LIMIT语句检索关注的“学生”周围的所有学生的范围(这是使用PHP语言不可避免的);所以像下面这样的代码可能就能完成这项工作:
$user = 'C'; // Student user we want to "focus"
$range = 1; // Range around the "focus" : 1 before and 1 after (could be changed to anything else)
// First query : retrieving the rank of the "focused" student
$stmt = $mysqli->prepare('SELECT COUNT(*) AS Rank FROM Student AS Focused INNER JOIN Student as Others ON Others.Score > Focused.Score OR (Others.Score = Focused.Score AND Others.Id > Focused.Id) WHERE Focused.user = ?');
$stmt->bind_param('s',$user);
$stmt->execute();
$res = $stmt->get_result()->fetch_assoc();
$startRank = $res['Rank'];
// Computing the dynamic LIMIT
if (($startRank - $range) < 1) {
$offset = 0;
$rowCount = $startRank + $range + 1;
} else {
$offset = $startRank - $range;
$rowCount = ($range * 2)+1;
}
// Second query : retrieving the rank of all the students around the "focused" student
$stmt = $mysqli->prepare('SELECT id, user, score, @curRank := @curRank + 1 AS rank FROM Student, (SELECT @curRank := ?) Rank ORDER BY Score DESC, id DESC LIMIT ?, ?');
$stmt->bind_param('iii',$offset,$offset,$rowCount);
$stmt->execute();这可能是查询数据库以获得所需内容的最优化方式。作为额外奖励,您可以将范围更改为您喜欢的任何内容。
https://stackoverflow.com/questions/26133628
复制相似问题