MySQL关联MAX(Date)查询时academic_session ID错误问题求助
解决学生最新注册记录的academic_session ID匹配问题
嗨,我明白你遇到的问题了!你原来的SQL里,当只按student分组时,academic_session列既没有被包含在GROUP BY里,也没有用聚合函数处理,这时候数据库会随机返回该学生任意一条注册记录的academic_session ID,而不是对应最大start_date的那个ID——这就是为啥max(start_date)对了,但ID不对的原因。
下面给你两种可靠的解决方案,都是标准SQL写法,兼容性好:
方案1:使用窗口函数(推荐,逻辑清晰)
窗口函数ROW_NUMBER()可以帮你给每个学生的注册记录按start_date倒序排名,最新的那条排名为1,直接筛选出来就行:
WITH ranked_registrations AS ( SELECT scr.student, scr.academic_session, asess.start_date, -- 按学生分组,按开学日期倒序排,最新的记录排第1 ROW_NUMBER() OVER (PARTITION BY scr.student ORDER BY asess.start_date DESC) AS rank_num FROM student_course_registration scr INNER JOIN academic_session asess ON scr.academic_session = asess.id WHERE scr.student = 101366 ) SELECT student, academic_session, start_date FROM ranked_registrations WHERE rank_num = 1;
如果同一个学生在同一个最新学年有多个注册记录,这个方法会返回其中一条;要是想返回所有同最新学年的记录,可以把ROW_NUMBER()换成RANK()或者DENSE_RANK()。
方案2:子查询获取最大日期后关联
先通过子查询找到该学生对应的最大start_date,再关联回去找到对应的学年ID和注册记录:
SELECT scr.student, scr.academic_session, asess.start_date FROM student_course_registration scr INNER JOIN academic_session asess ON scr.academic_session = asess.id WHERE scr.student = 101366 AND asess.start_date = ( -- 子查询拿到该学生的最晚开学日期 SELECT MAX(asess_inner.start_date) FROM student_course_registration scr_inner INNER JOIN academic_session asess_inner ON scr_inner.academic_session = asess_inner.id WHERE scr_inner.student = 101366 );
这个方法会返回该学生所有对应最新学年的注册记录,如果只需要一条,可以在末尾加LIMIT 1(MySQL、PostgreSQL等)或者FETCH FIRST 1 ROW ONLY(SQL Server、Oracle等)。
为啥原来的SQL不行?
标准SQL要求:SELECT列表里的列要么在GROUP BY子句中,要么被聚合函数(比如MAX()、MIN())包裹。有些数据库(比如MySQL在非严格模式下)允许违反这个规则,但返回的非聚合列值是不确定的,完全依赖数据库的内部实现,所以结果不可靠。
内容的提问来源于stack exchange,提问作者Roy
相关产品推荐
相关产品推荐

