2017-06-26 3 views
0

Je rencontre un problème en écrivant une requête qui saisit/calcule la moyenne de trois scores aux tests spécifiques pour un étudiant. Considérez la table TEST_SCORES suivante:Obtenir le score AVG du score le plus élevé pour chaque test

ID Name TestCode Score 
----------------------------- 
119 Joe  MCA  108 
119 Joe  BRT  98 
119 Joe  LPO  76 
119 Joe  BRT  111 
119 Joe  ALK  83 
119 Joe  MCA  100 
119 Joe  RTK  75 

For my scenario, I only want to consider scores from the "MCA" test, 
the "BRT" test, and the "RTK" test. I need the average of those tests. 
Also, I want to take the highest grade received for those 
tests (This is where I get stuck at). The following is what I have 
so far: 

SELECT A.ID, avg(A.Score) 
FROM TEST_SCORES A 
WHERE A.TestCode in ('MCA','BRT','RTK') 
AND A.ID = 119 
GROUP BY A.ID 

Il y a plus d'une entrée de score pour cet étudiant pour le test « BRT » et le test « MCA ». J'essaie d'obtenir le score du test MAX pour chaque test. J'essaie d'utiliser une condition pour saisir le score maximum, mais je continue à me retrouver avec la période de test la plus élevée, contrairement à la moyenne des trois tests.

Toute aide à ce sujet serait grandement appréciée. Merci d'avance.

+0

pouvez-vous publier le résultat attendu et marquer la base de données en cours d'utilisation? –

+0

Votre question est source de confusion. Des sons comme vous voulez juste grouper par testcode, aussi, cependant. Vous savez, vous pouvez regrouper par plusieurs colonnes, non? – fancyPants

+0

en effet, group by id, testcode devrait faire l'affaire. –

Répondre

0

obtiennent le max score par ID, testCode d'abord, puis avg ces scores par ID.

SELECT ID,AVG(maxScore) as avgScore 
FROM (SELECT ID,TestCode,MAX(Score) as maxScore 
     FROM TEST_SCORES 
     WHERE TestCode in ('MCA','BRT','RTK') 
     GROUP BY ID,TestCode 
    ) t 
GROUP BY ID 
+0

Cela fonctionne! Merci. Cela me rendait fou. Quelque chose de si simple ... – user1898629

0

La configuration est pas optimale (le nom ne doit pas apparaître dans ce tableau, il devrait être dans une petite table de recherche associant un nom à chaque ID comme indiqué dans l'illustration ci-dessous). A part cela, en fonction de votre version d'Oracle, que vous devriez toujours inclure dans votre question, vous pouvez ou ne pouvez pas utiliser la clause lateral (disponible depuis Oracle 12.1) pour une solution plus efficace, en un seul passer les données - même si vous avez besoin du score moyen pour tous les étudiants, pas seulement pour un seul. Une autre observation cependant - si un étudiant n'a pas pris l'un des examens (codes d'examen) du tout, cet examen ne sera pas considéré dans le calcul AT ALL, au lieu d'être moyenné avec un score de 0 (comme est généralement le cas dans la vraie vie). La réponse acceptée ne gère pas cette possibilité, pas plus que la solution ci-dessous. Si cela doit être traité alors vous devez clarifier votre question/exigence.

with 
    test_data (id, testcode, score) as (
     select 119, 'MCA', 108 from dual union all 
     select 119, 'BRT', 98 from dual union all 
     select 119, 'LPO', 76 from dual union all 
     select 119, 'BRT', 111 from dual union all 
     select 119, 'ALK', 83 from dual union all 
     select 119, 'MCA', 100 from dual union all 
     select 119, 'RTK', 75 from dual union all 
     select 200, 'ABC', 110 from dual union all 
     select 200, 'LPO', 90 from dual union all 
     select 200, 'BRT', 90 from dual union all 
     select 200, 'ALK', 102 from dual union all 
     select 200, 'LPO', 90 from dual 
    ), 
    students (id, name) as (
     select 119, 'Joe' from dual union all 
     select 200, 'Ann' from dual 
    ) 
select s.id, s.name, avgscore 
from students s, 
     lateral (select avg(max(score)) as avgscore 
       from  test_data t 
       where t.id = s.id 
        and testcode in ('MCA','BRT','RTK') 
       group by testcode 
       ) 
; 

ID NAME AVGSCORE 
--- ---- -------- 
119 Joe   98 
200 Ann   90