Традиционният метод е аналитичен
MAX()
(или друга аналитична функция):
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
Но вероятно бих предпочел да използвам ПЪРВО (ЗАПАЗИ).
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'
Предимствата и на двата подхода спрямо това, което първоначално предлагате, е, че сканирате таблицата само веднъж, няма нужда да осъществявате достъп нито до таблицата, нито до индекса втори път. Мога силно да препоръчам публикацията в блога на Rob van Wijk за разликите между двете.
P.S. те ще върнат различни резултати, така че са малко по-различни. Аналитичната функция ще поддържа дубликати, ако двама студенти имат еднакъв максимален резултат (това ще направи и вашето предложение). Функцията за обобщаване ще премахне дубликати, връщайки произволен запис в случай на равенство.