Reputation: 1912
I am trying to list students who received a below average grade on the 3rd quiz.
first I select
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
and I get four results that received average
STUDENT_ID LAST_NAME GRADE
---------- ------------------------- ----------
178 Kurtz 98
215 Chatman 90
259 Merriman 81
214 Williams 99
but when I want to select those who did receive below average I get 165 rows selected
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;
What am I doing wrong and how can I list students who received a below average grade ?
Upvotes: 0
Views: 132
Reputation: 62841
If I understand your question correctly, here is a simplified version using a common table expression
utilizing 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)
Upvotes: 3