Den traditionelle metode er en analytisk
MAX()
(eller anden 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 jeg ville nok foretrække at bruge FØRST (BEHOLD).
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'
Fordelene ved begge disse tilgange i forhold til det, du oprindeligt foreslår, er, at du kun scanner tabellen én gang, der er ingen grund til at få adgang til hverken tabellen eller indekset en anden gang. Jeg kan varmt anbefale Rob van Wijks blogindlæg om forskellene mellem de to.
P.S. disse vil returnere forskellige resultater, så de er lidt forskellige. Den analytiske funktion vil vedligeholde dubletter, hvis to elever har den samme maksimale score (det vil dit forslag også gøre). Den samlede funktion vil fjerne dubletter og returnere en tilfældig post i tilfælde af uafgjort.