Oracle
 sql >> Database >  >> RDS >> Oracle

subquery - ottenendo il punteggio più alto

Il metodo tradizionale è un analitica MAX() (o altra funzione analitica):

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

Ma probabilmente preferirei usare PRIMO (MANTENERE).

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'

I vantaggi di entrambi questi approcci rispetto a quanto suggerito inizialmente sono che si esegue la scansione della tabella solo una volta, non è necessario accedere alla tabella o all'indice una seconda volta. Consiglio vivamente post del blog di Rob van Wijk sulle differenze tra i due.

PS questi restituiranno risultati diversi, quindi sono leggermente diversi. La funzione analitica manterrà i duplicati se due studenti avessero lo stesso punteggio massimo (questo è ciò che farà anche il tuo suggerimento). La funzione di aggregazione rimuoverà i duplicati, restituendo un record casuale in caso di parità.