MySQL技术问询:如何获取每位学生最近一次测试的成绩数据?
嘿,这个需求我太熟了!要拿到每个学生仅最近一次测试的成绩,关键是先锁定每个学生的最新测试日期,再把对应日期的成绩捞出来就行。下面给你两种实用的MySQL写法,适配不同版本:
方法1:子查询关联法(兼容所有MySQL版本)
这种写法不需要依赖高版本特性,所有MySQL版本都能跑。先通过子查询找出每个学生的最新测试日期,再和原表关联筛选:
SELECT tr.* FROM test_results tr INNER JOIN ( -- 先按学生分组,拿到每个学生的最近测试日期 SELECT student, MAX(answered_on) AS latest_test_date FROM test_results GROUP BY student ) AS student_latest_dates ON tr.student = student_latest_dates.student AND tr.answered_on = student_latest_dates.latest_test_date;
简单说下逻辑:
- 子查询
student_latest_dates会给每个学生返回他的最大answered_on值,也就是最近一次测试的日期 - 把原表和这个子查询关联,只保留学生ID匹配且测试日期等于最新日期的记录,这样就得到了每个学生最近一次测试的所有题目成绩
方法2:窗口函数法(MySQL 8.0+推荐)
如果你的MySQL版本是8.0或更高,用窗口函数会更简洁直观,代码可读性也更强:
SELECT student, question_id, score, answered_on FROM ( SELECT *, -- 按学生分组,每组内按测试日期倒序排,给每条记录打行号 ROW_NUMBER() OVER (PARTITION BY student ORDER BY answered_on DESC) AS record_rank FROM test_results ) AS ranked_test_records WHERE record_rank = 1;
这里的逻辑:
PARTITION BY student把数据按学生拆分成独立的组,每组内按answered_on降序排序,最近的测试排在最前面ROW_NUMBER()给每组内的记录分配行号,最近一次测试的所有记录行号都是1(如果同一天有多个测试记录,ROW_NUMBER()会随机选一条;如果要保留同一天的所有测试,把ROW_NUMBER()换成RANK()就行)- 最后筛选行号为1的记录,就是每个学生最近一次测试的成绩
内容的提问来源于stack exchange,提问作者sliceofpie
相关产品推荐
相关产品推荐

