2009-03-26 9 views
2

J'ai une table avec 3 champs comme celui-ci:Comment obtenir les deux meilleurs étudiants de chaque professeur en SQL?

ProfessorID StudentID Mark 
P1    S1    9 
P1    S2    8 
P1    S3    10 
P2    S1    7 
P2    S2    2 
P2    S3    4 
P3    S4    5 
P4    S1    6 

Un professeur peut enseigner beaucoup d'étudiants, et vice versa, un étudiant peut apprendre beaucoup de professeur. Quand un étudiant apprend d'un professeur, il obtient sa marque.

Mon problème est de montrer la liste des professeurs qui enseignent à au moins 2 étudiants, et 2 étudiants qui obtiennent les meilleures notes de ces professeurs. Dans l'exemple, le résultat de la requête de ce tableau est le suivant:

ProfessorID StudentID Mark 
P1    S1    9 
P1    S3    10 
P2    S1    7 
P2    S3    4 

J'ai essayé quelques solutions, mais ils ne fonctionnent pas droit.

Comment est-ce que je peux faire ceci correctement?

+0

Il est marqué comme devoirs, poster ce que vous avez essayé, vous pointera dans la bonne direction – Martin

Répondre

3
declare @table table (ProfessorID nvarchar(2), StudentID nvarchar(2),Mark int) 

insert into @table 
select 'P1', 'S1', 9 
union all 
select 'P1', 'S2', 8 
union all 
select 'P1', 'S3', 10 
union all 
select 'P2', 'S1', 7 
union all 
select 'P2', 'S2', 2 
union all 
select 'P2', 'S3', 4 
union all 
select 'P3', 'S4', 5 
union all 
select 'P4', 'S1', 6 

select * 
from @table o 
where o.StudentID IN (select top 2 s.StudentID from @table s where s.ProfessorId = o.ProfessorId order by Mark DESC) 
and o.ProfessorID IN (select p.ProfessorID from @table p group by p.ProfessorID having count(*) >= 2)
+0

Intéressant ... devra revoir cela quand je serai plus éveillé. – CodeRedick

-1
SELECT ProfessorID, StudentID, MAX(Mark) 
FROM table 
GROUP BY ProfessorID, StudentID 
+0

Ce ne sera pas restreint par les professeurs avec deux ou plusieurs étudiants de plus, ni restreindre aux 2 meilleurs scores. – cmsjr

+0

:) cela ne fonctionne tout simplement pas correctement – Vimvq1987

+0

Mon mauvais ... lire la question trop vite. – atfergs

0

Asuming vous voulez dans SQL Server 2005 (ou 2008), cela fonctionnera aussi bien

select * 
from 
(
select * 
    ,rank() over (partition by professorid order by mark desc) as ranking 
    ,(select count(distinct studentid) 
     from marks m2 
     where m2.professorid = m1.professorid 
     group by professorid 
     ) as students 
from marks m1 
) subs 
where ranking < 3 
and students > 2 

-Edoode

0

Je viens de me réveiller ... mais goes here :

select * 
FROM 
    (select professorID, count(distinct studentID) as studentsTaught 
    FROM table 
    ) s 
WHERE s.studentsTaught = 2 
UNION ALL  
SELECT top 2 * 
FROM table 
WHERE professorID IN (select professorID 
         FROM (
          select professorID, count(distinct studentID) as studentsTaught 
          FROM table 
          ) s 
        ) 
WHERE s.studentsTaught = 2 
ORDER BY mark 

Devrait fonctionner ... fondamentalement vous interrogez le pr ofesors et en les comptant comme une sous-requête, puis en sélectionnant ceux qui ont 2 étudiants de cette sous-requête. Pour leurs étudiants, vous devez les UNION et de trouver les mêmes professeurs, mais ORDER BY est assez bon pour obtenir les deux meilleurs étudiants.

+0

Je ne suis pas sûr qu'une union est nécessaire pour cette requête – Martin

+0

C'est comme ça que je l'ai fait ...;) – CodeRedick

Questions connexes