
高效获取MySQL中每个学生的最高分
本文介绍如何从MySQL的score表中,高效地查询每个学生的最高分,特别是当一个学生在同一天可能有多个分数记录的情况。
问题与错误方法
直接使用GROUP BY和HAVING语句来筛选最高分,在存在同一天多个分数记录时会失效,导致查询结果为空或不准确。
解决方案:使用窗口函数
利用MySQL的窗口函数ROW_NUMBER(),可以优雅地解决这个问题。
本书是全面讲述PHP与MySQL的经典之作,书中不但全面介绍了两种技术的核心特性,还讲解了如何高效地结合这两种技术构建健壮的数据驱动的应用程序。本书涵盖了两种技术新版本中出现的最新特性,书中大量实际的示例和深入的分析均来自于作者在这方面多年的专业经验,可用于解决开发者在实际中所面临的各种挑战。 本书内容全面深入,适合各层次PHP和MySQL开发人员阅读,既是优秀的学习教程,也可用作参考手册。
以下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的记录,即每个学生的最高分记录。
- 从内查询生成的临时表
此方法能够有效处理一个学生在同一天有多个分数的情况,确保返回每个学生真正意义上的最高分。









