Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Unterabfrage - Erzielen der höchsten Punktzahl

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.