下面的AVG子查询没有显示正确的结果

时间:2013-10-18 04:25:32

标签: sql oracle

我试图列出在第3次测验中获得低于平均成绩的学生。

首先我选择

SELECT s.STUDENT_ID, s.LAST_NAME,g.GRADE_TYPE_CODE,AVG (g.NUMERIC_GRADE) AS GRADE
FROM STUDENT s, GRADE g
WHERE s.STUDENT_ID = g.STUDENT_ID
AND g.SECTION_ID = 135 AND g.GRADE_TYPE_CODE= 'QZ' AND g.GRADE_CODE_OCCURRENCE = 3 
GROUP BY s.STUDENT_ID, s.LAST_NAME,g.GRADE_TYPE_CODE

我得到四个收到平均值的结果

STUDENT_ID LAST_NAME                      GRADE
---------- ------------------------- ----------
   178      Kurtz                             98 
   215      Chatman                           90 
   259      Merriman                          81 
   214      Williams                          99 

但是当我想选择那些收到低于平均值的人时,我会选择165行

  SELECT z.STUDENT_ID, z.LAST_NAME
  FROM STUDENT z, GRADE w
  WHERE z.STUDENT_ID = w.STUDENT_ID
  GROUP BY z.STUDENT_ID, z.LAST_NAME
  HAVING COUNT(*) < 
  (SELECT AVG(GRADE) 
  FROM
  (SELECT s.STUDENT_ID, s.LAST_NAME,g.GRADE_TYPE_CODE,AVG (g.NUMERIC_GRADE) AS GRADE
  FROM STUDENT s, GRADE g
  WHERE s.STUDENT_ID = g.STUDENT_ID
  AND g.SECTION_ID = 135 AND g.GRADE_TYPE_CODE= 'QZ' AND g.GRADE_CODE_OCCURRENCE = 3 
  GROUP BY s.STUDENT_ID, s.LAST_NAME,g.GRADE_TYPE_CODE ))

 ORDER BY z.LAST_NAME;

我做错了什么,如何列出收入低于平均成绩的学生?

1 个答案:

答案 0 :(得分:3)

如果我正确理解您的问题,请使用common table expression使用avg() over()的简化版本:

with cte as (
  select s.student_id, s.last_name, g.numeric_grade,
    avg(g.numeric_grade) over () average
  from student s
    join grade g on s.student_id = g.student_id
  where g.section_id = 135 
    and g.grade_type_code = 'QZ' 
    and g.grade_code_occurence = 3
  )
select student_id, last_name
from cte
group by student_id, last_name
having avg(numeric_grade) < avg(average)