AYANT – GROUP BY pour get le dernier record

J'ai une table appelée RÉSULTATS comme ceci:

RESULTS_IDN NAME SUBJECT YEAR QUALIFIED 1 MARK ENGLISH 1989 N 3 MARK ENGLISH 1991 N 5 MARK ENGLISH 1993 Y 7 MARK ENGLISH 1995 N 2 MARK MATH 1990 N 5 MARK MATH 1993 N 6 MARK MATH 1995 Y 4 MARK SCIENCE 1991 N 9 MARK SCIENCE 1997 Y 

J'ai besoin de connaître le statut de qualification du CANDIDAT pour un SUJET pour le dernier examen qu'il a écrit, comment puis-je écrire une requête pour cela (ORACLE / MSSQL)?

Par exemple Entrée

 NAME,SUBJECT OUTPUT NAME IDN SUBJECT YEAR Q MARK,ENGLISH OUTPUT MARK 7 ENGLISH 1995 N MARK SCIENCE OUTPUT MARK 9 SCIENCE 1997 Y MARK MATH OUTPUT MARK 6 MATH 1995 Y 

Je connais une façon de résoudre cela.

 (SELECT NAME SUBJECT YEAR MAX(YEAR) YEAR FROM RESULTS WHERE NAME = 'MARK' AND SUBJECT ='MATH' GROUP BY NAME SUBJECT YEAR) LATEST 

Rejoindre la table ci-dessus sur IDN à la même table et je peux get les résultats. Mais c'est un double travail. Y at-il de toute façon que je peux enstringr le MAX (YEAR) et get l'ANNÉE CORRESPONDANTE en utilisant la CLAUSE HAVING ou quelque chose? J'ai besoin de 2 opérations sur datatables GROUP BY, une dernière, et le statut Qualifié corresponidng.

PS: Bien sûr, il y a des records pour 100 candidats comme ça dans la DB.

Mise à jour: Cette question est également catégorisée comme le problème le plus grand par n-groupe selon la réponse 2. Intéressant de savoir qu'il s'agit d'un problème classifié dans la database.

Dans Oracle et SQL Server, vous pouvez utiliser les fonctions analytiques / de fenêtrage RANK () ou ROW_NUMBER () pour cela:

 select * from ( select a.* , rank() over ( partition by name, subject order by year desc ) rnk from ... a ) where rnk = 1 

RANK () returnnera 1 pour chaque ligne qui est la plus récente par name et subject , ROW_NUMBER () returnnera une ligne random .

Dans Oracle seul, vous pouvez utiliser KEEP pour get le même résultat:

 select name, subject, max(year) as year , max(qualified) keep (dense_rank first order by year desc) as qualified from ... group by name, subject 

C'est le problème réinventé de plus-n-par-groupe :

 SELECT t1.* FROM RESULTS AS t1 LEFT JOIN RESULTS AS t2 ON t1.NAME = t2.NAME AND t1.SUBJECT = t2.SUBJECT AND t1.YEAR < t2.YEAR WHERE t2.NAME IS NULL