MySQL中MAX()与GROUP BY()查询结果不符合预期的问题
解决按Form分组获取学生最高Percentage的SQL问题
你原来的查询是为了获取2018年第3学期学生的remark数据,但当你尝试用MAX(m.Percentage)和GROUP BY sc.Form时,结果不符合预期——这是因为GROUP BY sc.Form会把同一个Form下的所有行合并成一行,但未被聚合的列(比如stdClassID、ClassID、stdName等)会被数据库随机选取,无法保证和最高Percentage的那一行对应。
下面给你两种可靠的解决方案,能准确拿到每个Form中Percentage最高的学生数据:
方法一:使用窗口函数(推荐,可读性高)
窗口函数可以帮我们在每个Form分组内对学生的Percentage进行排名,然后直接取排名第一的行:
WITH ranked_remarks AS ( SELECT m.stdClassID, m.Percentage, sc.ClassID, sc.Form, sc.FormName, sc.Year, sc.stdName, -- 按Form分组,组内按Percentage降序排名,最高分排第1 ROW_NUMBER() OVER (PARTITION BY sc.Form ORDER BY m.Percentage DESC) AS rn FROM stdremark m INNER JOIN ( SELECT sc.ClassID, c.Form, c.FormName, sc.stdClassID, c.Year, CONCAT(s.StdFname,' ',s.StdLname) as stdName FROM tblstdclass sc INNER JOIN tblclass c ON sc.ClassID=c.ClassID INNER JOIN tblstudents s ON sc.StdID = s.StdID WHERE c.Year=2018 ) sc ON m.stdClassID=sc.stdClassID WHERE m.Term=3 ) SELECT stdClassID, Percentage, ClassID, Form, FormName, Year, stdName FROM ranked_remarks WHERE rn = 1; -- 筛选每个Form中排名第一(最高分)的行
方法二:使用子查询匹配最高分
先通过子查询算出每个Form的最高Percentage,再关联回原查询找到对应的学生信息:
SELECT m.stdClassID, m.Percentage, sc.ClassID, sc.Form, sc.FormName, sc.Year, sc.stdName FROM stdremark m INNER JOIN ( SELECT sc.ClassID, c.Form, c.FormName, sc.stdClassID, c.Year, CONCAT(s.StdFname,' ',s.StdLname) as stdName FROM tblstdclass sc INNER JOIN tblclass c ON sc.ClassID=c.ClassID INNER JOIN tblstudents s ON sc.StdID = s.StdID WHERE c.Year=2018 ) sc ON m.stdClassID=sc.stdClassID WHERE m.Term=3 AND (sc.Form, m.Percentage) IN ( -- 子查询:算出每个Form的最高Percentage SELECT sc_inner.Form, MAX(m_inner.Percentage) FROM stdremark m_inner INNER JOIN ( SELECT sc.ClassID, c.Form, sc.stdClassID FROM tblstdclass sc INNER JOIN tblclass c ON sc.ClassID=c.ClassID WHERE c.Year=2018 ) sc_inner ON m_inner.stdClassID=sc_inner.stdClassID WHERE m_inner.Term=3 GROUP BY sc_inner.Form );
这两种方法都能得到你期望的结果,比如你提到的:
17 71 28 upper Science 2018 Jerry Maguire
内容的提问来源于stack exchange,提问作者Akshay
相关产品推荐
相关产品推荐

