高效获取MySQL中每个学生的最高分
本文介绍如何从MySQL的score
表中,高效地查询每个学生的最高分,特别是当一个学生在同一天可能有多个分数记录的情况。
问题与错误方法
直接使用GROUP BY
和HAVING
语句来筛选最高分,在存在同一天多个分数记录时会失效,导致查询结果为空或不准确。
解决方案:使用窗口函数
利用MySQL的窗口函数ROW_NUMBER()
,可以优雅地解决这个问题。
以下SQL语句能够准确返回每个学生的最高分记录:
SELECT id, student_id, score, date
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY student_id ORDER BY score DESC, date DESC) AS ranking
FROM score
) AS tmp
WHERE ranking = 1;
代码解释:
内查询: SELECT *, ROW_NUMBER() OVER (PARTITION BY student_id ORDER BY score DESC, date DESC) AS ranking FROM score
ROW_NUMBER() OVER (PARTITION BY student_id ORDER BY score DESC, date DESC)
: 这是关键部分。PARTITION BY student_id
将数据按照student_id
分组,为每个学生单独计算排名。ORDER BY score DESC, date DESC
指定排序规则:先按分数降序,分数相同则按日期降序。 这样,每个学生最高分的那条记录的ranking
值为1。外查询: SELECT id, student_id, score, date FROM (...) AS tmp WHERE ranking = 1;
tmp
中选择ranking
值为1的记录,即每个学生的最高分记录。此方法能够有效处理一个学生在同一天有多个分数的情况,确保返回每个学生真正意义上的最高分。