Die herkömmliche Methode ist eine Analyse
MAX()
(oder andere analytische 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
Aber ich würde es wahrscheinlich vorziehen, ZUERST zu verwenden (BEHALTEN).
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'
Der Vorteil dieser beiden Ansätze gegenüber dem, was Sie ursprünglich vorschlagen, besteht darin, dass Sie die Tabelle nur einmal scannen und weder auf die Tabelle noch auf den Index ein zweites Mal zugreifen müssen. Ich kann Rob van Wijks Blogpost wärmstens empfehlen über die Unterschiede zwischen den beiden.
P.S. diese werden unterschiedliche Ergebnisse zurückgeben, also sind sie etwas anders. Die Analysefunktion behält Duplikate bei, wenn zwei Schüler die gleiche maximale Punktzahl haben (das wird auch Ihr Vorschlag tun). Die Aggregatfunktion entfernt Duplikate und gibt im Falle eines Unentschiedens einen zufälligen Datensatz zurück.