問題をいくつかの一口サイズのステップに分割し、それぞれを 1 つずつ解決する必要があります。
まず、各科目の最高得点を取得します。
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 テストは、他の名前による結合です。
これを変換して..
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 キーワードは実際には長くなります。独立したクエリの列の結果 ( max(MarkRate) AS MarkRate
) とサブクエリ自体 ( as x
) にエイリアスを設定する必要があります。とにかく、これはスタイルの問題です。意図がより明確であるため、IN句を好みます。データ関係を反映するためだけに JOIN を使用する。
IN
とにかく、タプル test( )をサポートしていないすべてのデータベースで機能するクエリは次のとおりです。
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