如何通过两张SQL表的数据正确计算学生GPA
GPA计算SQL修正方案
错误原因
原更新语句的子查询没有和外层待更新的学生ID做关联,导致子查询始终返回全表所有学生的绩点加权平均值,所有学生的GPA都会被赋值为同一个全局平均结果。
修正后的SQL
写法1:子查询匹配模式(兼容大多数SQL方言)
UPDATE student s SET GPA = ( SELECT SUM(t.gradeWeight * c.c_cHr) / SUM(c.c_cHr) FROM student t INNER JOIN Course c ON t.c_name = c.c_name WHERE t.s_id = s.s_id GROUP BY t.s_id )
写法2:CTE关联更新模式(数据量大时效率更高,适配SQL Server)
WITH student_gpa AS ( SELECT t.s_id, SUM(t.gradeWeight * c.c_cHr) / SUM(c.c_cHr) AS calc_gpa FROM student t INNER JOIN Course c ON t.c_name = c.c_name GROUP BY t.s_id ) UPDATE s SET s.GPA = g.calc_gpa FROM student s INNER JOIN student_gpa g ON s.s_id = g.s_id
补充说明
- 修正方案去掉了不必要的
studMark表关联:因为student表的gradeWeight字段已经提前完成计算,直接用student表的选课、绩点数据关联课程表计算学分加权即可,减少多余关联提升效率 - 新增子查询与外层的
s_id关联逻辑,保证每次仅计算当前待更新学生的个人绩点 - 如果需要兼容无选课记录的学生,避免GPA被赋值为NULL,可以用
COALESCE包裹子查询:SET GPA = COALESCE((子查询), 0)
额外小提示:你之前更新
gradeWeight的SQL里写了WHEN grade='c',但给grade字段赋值时用的是大写C,大小写不匹配会导致C等级的绩点权重计算为NULL,建议统一改成大写WHEN grade='C'避免出错。
内容的提问来源于stack exchange,提问作者ask123
相关产品推荐
相关产品推荐

