MySQL:查询指定学生各topic与section_type组合的最早测试结果
高效查询学生首次测试的各题型结果方案
针对你的需求,推荐使用**窗口函数ROW_NUMBER()**的写法,相比多子查询,它能减少表扫描次数,执行效率更高,逻辑也更清晰:
SELECT topic, section_type, result FROM ( SELECT ts.topic, ts.section_type, ts.result, ROW_NUMBER() OVER ( PARTITION BY ts.topic, ts.section_type ORDER BY t.test_date ASC ) AS rn FROM test_section ts JOIN test t ON ts.test_id = t.test_id WHERE t.student_id = @target_student_id -- 替换为指定的student_id ) AS ranked WHERE rn = 1;
写法说明
- 关联表:先将
test_section和test通过test_id关联,过滤出目标学生的所有测试记录 - 分组排序:用
PARTITION BY ts.topic, ts.section_type将记录按「知识点+题型」分组,再按test_date升序排序,给每组内的记录标记序号rn,首次测试的记录序号为1 - 筛选结果:外层查询只取
rn=1的记录,就是每个「知识点+题型」组合的首次测试结果
效率优势
- 相比多子查询(比如多次嵌套找最小test_date再关联),这个写法只需要一次表关联和一次排序操作,数据库能更好地优化执行计划
- 窗口函数是现代关系型数据库(MySQL 8.0+、PostgreSQL、SQL Server等)原生支持的特性,执行效率经过优化,数据量越大,优势越明显
适配场景
完全符合你的已知条件:每个test_id对应唯一test_date,且单个test_id下不会有重复的「知识点+题型」组合,因此分组排序后不会出现序号冲突的情况。
内容的提问来源于stack exchange,提问作者dylan
相关产品推荐
相关产品推荐

