我有一个包含3个字段的表:
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
教授可以教许多学生,反之亦然,学生可以向许多教授学习。当一个学生从教授那里学到东西时,他就会得到他的印记。
我的问题是显示教授至少2名学生的教授名单,以及2名从这些教授那里获得最佳分数的学生。例如,该表的查询结果为:
ProfessorID StudentID Mark
P1 S1 9
P1 S3 10
P2 S1 7
P2 S3 4
我尝试了一些解决方案,但它们无效正确。
我该如何正确地做到这一点?
答案 0 :(得分: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)
答案 1 :(得分:0)
假设你想在SQL 2005(或2008)中使用它,这也可以正常工作
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
答案 2 :(得分:0)
我刚刚醒来......但是这里有:
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
应该工作......基本上你是在询问教授并把它们算作子查询,然后从那个子查询中选择那些有2名学生的人。对于他们的学生,你必须联合他们并找到相同的教授,但是ORDER BY足以让两个最好的学生。
答案 3 :(得分:-1)
SELECT ProfessorID, StudentID, MAX(Mark)
FROM table
GROUP BY ProfessorID, StudentID