SQL HAVING子句过滤问题:两种最高分查询结果为何不同?
为什么两个获取最高分学生的查询结果不同?
需求:获取所有总分最高的学生(存在多名最高分学生的场景),但在MySQL 5.7.12中,以下两个查询结果存在差异:
查询1(仅返回1条结果)
SELECT * FROM ( SELECT SUM(points) total, student_id FROM student_score_per_subject_table GROUP BY student_id ORDER BY 1 DESC ) students HAVING total = MAX(total)
该查询仅返回1条结果,为student_id字典序最小的学生。
查询2(返回所有最高分学生)
SELECT * FROM ( SELECT SUM(points) total, student_id FROM student_score_per_subject_table GROUP BY student_id ORDER BY 1 DESC ) students HAVING total = 100 -- highest total score
该查询返回所有总分等于100的学生,符合预期。
原因分析
查询1的问题:
外层查询未指定GROUP BY,MySQL 5.7在这种场景下使用聚合函数MAX(total)时,会将整个子查询结果集视为单一分组,但结合子查询的ORDER BY排序逻辑,MySQL会错误地取排序后第一条数据的total值作为MAX(total)的结果,最终只会匹配到那一条数据,而非所有总分等于最高分的记录。查询2的正确性:
直接将total与已知的最高分(100)做等值匹配,只要学生总分等于100就会被筛选出来,自然能返回所有符合条件的最高分学生。
推荐的通用写法(无需硬编码最高分)
如果不想硬编码最高分,可以先通过子查询获取全局最高分,再做匹配:
SELECT SUM(points) total, student_id FROM student_score_per_subject_table GROUP BY student_id HAVING total = ( SELECT MAX(total) FROM ( SELECT SUM(points) total FROM student_score_per_subject_table GROUP BY student_id ) temp )
内容的提问来源于stack exchange,提问作者Memphis Meng
相关产品推荐
相关产品推荐

