Den traditionella metoden är en analytisk
MAX()
(eller annan analytisk funktion):
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
Men jag skulle förmodligen föredra att använda FÖRST (BEHÅLL).
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'
Fördelarna med båda dessa tillvägagångssätt jämfört med vad du först föreslår är att du bara skannar tabellen en gång, det finns ingen anledning att komma åt varken tabellen eller indexet en andra gång. Jag kan varmt rekommendera Rob van Wijks blogginlägg om skillnaderna mellan de två.
P.S. dessa kommer att ge olika resultat, så de skiljer sig något. Den analytiska funktionen kommer att upprätthålla dubbletter där två elever får samma maximala poäng (det här är vad ditt förslag kommer att göra också). Den sammanlagda funktionen tar bort dubbletter och returnerar en slumpmässig post i händelse av oavgjort.