您只需将问题划分为一些小步骤并逐个解决
首先,获得每个科目的最高分:
select SubjectID, max(MarkRate)
from Mark
group by SubjectID;
然后查询谁是具有最大 MarkRate 的 SubjectID:
select SubjectID, MarkRate, StudentID
from Mark
where (SubjectID,MarkRate)
in
(
select SubjectID, max(MarkRate)
from Mark
group by SubjectID
)
order by SubjectID, StudentID;
然后获取学生的姓名,而不是只显示 StudentID:
select SubjectName, MarkRate, StudentName
from Mark
join Student using(StudentID)
join Subject using(SubjectID)
where (SubjectID,MarkRate)
in
(
select SubjectID, max(MarkRate)
from Mark
group by SubjectID
)
order by SubjectName, StudentName
除了数据库厂商在加入和关联结果方面的人为差异外,基本步骤是相同的;首先,将问题分成一小部分,然后在解决每个问题时将它们整合起来,这样就不会那么混乱了。
样本数据:
CREATE TABLE Student
(StudentID int, StudentName varchar(6), Details varchar(1));
INSERT INTO Student
(StudentID, StudentName, Details)
VALUES
(1, 'John', 'X'),
(2, 'Paul', 'X'),
(3, 'George', 'X'),
(4, 'Paul', 'X');
CREATE TABLE Subject
(SubjectID varchar(1), SubjectName varchar(7));
INSERT INTO Subject
(SubjectID, SubjectName)
VALUES
('M', 'Math'),
('E', 'English'),
('H', 'History');
CREATE TABLE Mark
(StudentID int, SubjectID varchar(1), MarkRate int);
INSERT INTO Mark
(StudentID, SubjectID, MarkRate)
VALUES
(1, 'M', 90),
(1, 'E', 100),
(2, 'M', 95),
(2, 'E', 70),
(3, 'E', 95),
(3, 'H', 98),
(4, 'H', 90),
(4, 'E', 100);
现场测试:http ://www.sqlfiddle.com/#!1/08728/3
IN tuple test 仍然是任何其他名称的连接:
转换这个..
select SubjectName, MarkRate, StudentName
from Mark
join Student using(StudentID)
join Subject using(SubjectID)
where (SubjectID,MarkRate)
in
(
select SubjectID, max(MarkRate)
from Mark
group by SubjectID
)
order by SubjectName, StudentName
..加入:
select SubjectName, MarkRate, StudentName
from Mark
join Student using(StudentID)
join Subject using(SubjectID)
join
(
select SubjectID, max(MarkRate) as MarkRate
from Mark
group by SubjectID
) as x using(SubjectID,MarkRate)
order by SubjectName, StudentName
将此代码与直接它的代码进行对比。看看独立查询上的 JOIN 看起来如何像一个 IN 构造?它们看起来几乎一样,只是将 IN 替换为 JOIN 关键字;并且用 JOIN 替换的 IN 关键字实际上更长,您需要为独立查询的列 result( max(MarkRate) AS MarkRate
) 以及子查询本身 ( as x
) 取别名。无论如何,这只是风格问题,我更喜欢IN子句,因为意图更清晰。使用 JOIN 只是为了反映数据关系。
无论如何,这是适用于所有不支持元组 test( IN
) 的数据库的查询:
select sb.SubjectName, m.MarkRate, st.StudentName
from Mark as m
join Student as st on st.StudentID = m.StudentID
join Subject as sb on sb.SubjectID = m.SubjectID
join
(
select SubjectID, max(MarkRate) as MaxMarkRate
from Mark
group by SubjectID
) as x on m.SubjectID = x.SubjectID AND m.MarkRate = x.MaxMarkRate
order by sb.SubjectName, st.StudentName
现场测试:http ://www.sqlfiddle.com/#!1/08728/4