subquery - getting the highest score

╄→尐↘猪︶ㄣ 提交于 2019-12-11 03:45:37

问题


I am trying to get the student that scored highest on the final exam

first I select

SELECT s.STUDENT_ID, w.LAST_NAME,w.FIRST_NAME, MAX(s.NUMERIC_GRADE) AS NUMERIC_FINAL_GRADE
FROM GRADE s , SECTION z, STUDENT w
WHERE s.SECTION_ID = z.SECTION_ID AND s.STUDENT_ID = w.STUDENT_ID
AND z.COURSE_NO = 230 AND z.SECTION_ID = 100 AND s.GRADE_TYPE_CODE = 'FI'
GROUP BY s.STUDENT_ID, w.FIRST_NAME,w.LAST_NAME

and it gives me this result and that is what I want

 STUDENT_ID LAST_NAME                 FIRST_NAME                NUMERIC_FINAL_GRADE
  ---------- ------------------------- ------------------------- -------------------
   262 Walston                   Donna                                      85 
   141 Boyd                      Robert                                     84 

but when I try to get the max from these two it gives me no rows or an error

i.STUDENT_ID, k.LAST_NAME,k.FIRST_NAME
FROM GRADE i , SECTION j, STUDENT k
WHERE i.SECTION_ID = j.SECTION_ID AND i.STUDENT_ID = k.STUDENT_ID
AND j.COURSE_NO = 230 AND j.SECTION_ID = 100 AND i.GRADE_TYPE_CODE = 'FI' 
GROUP BY i.STUDENT_ID, k.FIRST_NAME,k.LAST_NAME
HAVING COUNT(*) =
(SELECT MAX(NUMERIC_FINAL_GRADE)
 FROM
(SELECT s.STUDENT_ID, w.LAST_NAME,w.FIRST_NAME, MAX(s.NUMERIC_GRADE) AS NUMERIC_FINAL_GRADE
FROM GRADE s , SECTION z, STUDENT w
WHERE s.SECTION_ID = z.SECTION_ID AND s.STUDENT_ID = w.STUDENT_ID
AND z.COURSE_NO = 230 AND z.SECTION_ID = 100 AND s.GRADE_TYPE_CODE = 'FI'
GROUP BY s.STUDENT_ID, w.FIRST_NAME,w.LAST_NAME))

ORDER BY i.STUDENT_ID, k.LAST_NAME,k.FIRST_NAME;

How can I get max result from these two results that I already have and why does it give me no rows or an error ?


回答1:


The traditional method is an analytic MAX() (or other analytic function):

select *
  from ( select s.student_id
              , w.last_name
              , w.first_name
              , s.numeric_grade
              , max(s.numeric_grade) over () as numeric_final_grade
           from grade s
           join section z
             on s.section_id = z.section_id
           join student w
             on s.student_id = w.student_id
          where z.course_no = 230 
            and z.section_id = 100 
            and s.grade_type_code = 'FI'
                )
 where numeric_grade = numeric_final_grade

But I would probably prefer using FIRST (KEEP).

select max(s.student_id) keep (dense_rank first order by s.numeric_grade desc) as student_id
     , max(w.last_name) keep (dense_rank first order by s.numeric_grade desc) as last_name
     , max(w.first_name) keep (dense_rank first order by s.numeric_grade desc) as first_na,e
     , max(s.numeric_grade_name) as numeric_final_grade
  from grade s
  join section z
    on s.section_id = z.section_id
  join student w
    on s.student_id = w.student_id
 where z.course_no = 230 
   and z.section_id = 100 
   and s.grade_type_code = 'FI'

The benefits of both of these approaches over what you initially suggest is that you only scan the table once, there's no need to access either the table or the index a second time. I can highly recommend Rob van Wijk's blog post on the differences between the two.

P.S. these will return different results, so they are slightly different. The analytic function will maintain duplicates were two students to have the same maximum score (this is what your suggestion will do as well). The aggregate function will remove duplicates, returning a random record in the event of a tie.




回答2:


SELECT * FROM 
(
  SELECT s.STUDENT_ID, w.LAST_NAME,w.FIRST_NAME, 
     MAX(s.NUMERIC_GRADE) AS NUMERIC_FINAL_GRADE
  FROM GRADE s, SECTION z, STUDENT w
  WHERE s.SECTION_ID = z.SECTION_ID 
     AND s.STUDENT_ID = w.STUDENT_ID
     AND z.COURSE_NO = 230 AND z.SECTION_ID = 100 
     AND s.GRADE_TYPE_CODE = 'FI'
  GROUP BY s.STUDENT_ID, w.FIRST_NAME, w.LAST_NAME
  ORDER BY MAX(s.NUMERIC_GRADE)
) AS M 
WHERE ROWNUM <= 1


来源:https://stackoverflow.com/questions/19435503/subquery-getting-the-highest-score

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!