如何从数据对中提取单行数据?附可用但低效的SQL代码
嘿,我看你这段SQL是想对比教员和同部门同事的课程平均成绩,但写得有点冗余,重复计算了两次平均成绩,肯定影响效率。而且你想要只返回一行结果,我帮你优化了一下,不仅逻辑更清晰,效率也能提上去:
优化后的SQL代码
WITH FacultyCourseAvg AS ( SELECT f.FacNo, f.FacFirstName + ' ' + f.FacLastName AS FacultyName, f.FacDept, o.CourseNo, AVG(e.EnrGrade) AS AverageGrade FROM Faculty f JOIN Offering o ON f.FacNo = o.FacNo JOIN Enrollment e ON o.OfferNo = e.OfferNo GROUP BY f.FacNo, f.FacFirstName, f.FacLastName, f.FacDept, o.CourseNo ) SELECT fc1.FacultyName, fc1.FacDept, fc2.FacultyName AS ColleagueName, fc2.FacDept AS ColleagueDept, fc1.CourseNo, fc1.AverageGrade AS FacultyAvgGrade, fc2.AverageGrade AS ColleagueAvgGrade FROM FacultyCourseAvg fc1 JOIN FacultyCourseAvg fc2 ON fc1.FacDept = fc2.FacDept -- 按同部门匹配同事 AND fc1.CourseNo = fc2.CourseNo -- 限定同一课程 AND fc1.FacNo <> fc2.FacNo -- 排除自己 -- 这里指定你要查询的特定教员和课程,确保返回单行 WHERE fc1.FacNo = 'F123' AND fc1.CourseNo = 'CS101' -- 不同数据库取单行的语法:SQL Server用TOP 1,Oracle用FETCH FIRST 1 ROW ONLY,MySQL用LIMIT 1 FETCH FIRST 1 ROW ONLY;
优化说明
- 避免重复计算:用CTE(公共表表达式)把教员课程平均成绩的计算逻辑抽出来,只执行一次,不像原查询那样写两个几乎一样的子查询,大大减少数据库的计算开销。
- 逻辑更清晰:把重复的逻辑封装成CTE后,主查询的关联逻辑一目了然,后期维护也方便。
- 精准控制单行结果:通过
WHERE条件锁定你需要的特定教员和课程,再加上取单行的语法,确保最终只返回一行数据。 - 简化字段处理:把姓名拼接和别名定义放在CTE里,主查询直接用,减少重复代码。
如果你的需求不是对比特定教员和同事,而是要把所有数据聚合为一行统计,随时说,我再调整方案~
内容的提问来源于stack exchange,提问作者AgentShaw
相关产品推荐
相关产品推荐

