Il metodo tradizionale è un analitica
MAX()
(o altra funzione analitica):
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
Ma probabilmente preferirei usare PRIMO (MANTENERE).
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'
I vantaggi di entrambi questi approcci rispetto a quanto suggerito inizialmente sono che si esegue la scansione della tabella solo una volta, non è necessario accedere alla tabella o all'indice una seconda volta. Consiglio vivamente post del blog di Rob van Wijk sulle differenze tra i due.
PS questi restituiranno risultati diversi, quindi sono leggermente diversi. La funzione analitica manterrà i duplicati se due studenti avessero lo stesso punteggio massimo (questo è ciò che farà anche il tuo suggerimento). La funzione di aggregazione rimuoverà i duplicati, restituendo un record casuale in caso di parità.