2013-12-08 62 views
0

我手邊有一項任務,要求我返回一位學生的姓名的詳細信息,這名學生是由霍夫曼的姓氏老師教授的課程,我被卡住了。postgresql多個子查詢

SELECT * FROM Public."Class" WHERE tid=(
     SELECT tid FROM Public."Tutor" WHERE tname LIKE '%Hoffman'); 

這讓我想起了霍夫曼教授的課程,但是從這裏我不確定要去哪裏。我相信我必須訪問「已註冊」表,然後才能訪問學生表,但嘗試無效。下面的查詢是我在得到查詢之前得到的。-_-我確定我將不得不使用HAVINGIN關鍵字,但我不知道如何處理它們!

SELECT * FROM Public."Student" WHERE programme='IT' (
    SELECT * FROM Public."Class" WHERE tid=(
     SELECT tid FROM Public."Tutor" WHERE tname LIKE '%Hoffman') 
    ); 

任何幫助將不勝感激!

的數據庫結構如下: - 再次:)

Student(sid integer, sname varchar(20), programme varchar(4), level integer, age integer) 
Class(ccode varchar(6), cname varchar(25), week_day varchar(3), meets_at time, room 
varchar(6), tid integer) 
Enrolled(sid integer, ccode varchar(6)) 
Tutor(tid integer, tname varchar(20)) 

感謝更新: -

SELECT DISTINCT * 
FROM Public."Student" s 
INNER JOIN Public."Enrolled" e ON e.sid = s.sid 
INNER JOIN Public."Class" c ON c.ccode = e.ccode 
INNER JOIN Public."Tutor" t ON t.tid = c.tid 
WHERE programme='IT' AND t.tname LIKE '%Hoffman'; 
+2

Pg教程非常值得一看:http://www.postgresql.org/docs/current/static/tutorial.html。 (不是很尖刻,只是對某人開始使用SQL提出一個誠實的建議)。 –

回答

2

兩個解決方案上面會導致學生被報道多次,如果他們在入學來自同一位老師的多個班級。如果查詢的唯一目標是僅選擇學生,則下面的查詢將完成該操作。

SELECT * 
FROM Student s 
WHERE s.programme = 'IT' 
AND EXISTS (
    SELECT * 
    FROM Enrolled e 
    JOIN Class c ON c.ccode = e.ccode 
    JOIN Tutor t ON t.tid = c.tid 
    WHERE e.sid = s.sid 
    AND t.tname LIKE '%Hoffman' 
); 
+0

我正在使用DISTINCT。這是不正確的?我會更新帖子以顯示當前查詢 – Timmy

+1

整個觀點是:你不需要明確。學生表中的學生已經是獨一無二的。 (我相信)。如果你不生成重複,你不必排除它們。 – wildplasser

5

你並不需要爲做子查詢每個驗證。這很容易做到與聯接:

SELECT s.* 
FROM Student s 
INNER JOIN Enrolled e ON e.sid = s.sid 
INNER JOIN Class c ON c.ccode = e.ccode 
INNER JOIN Tutor t ON t.tid = c.tid 
WHERE t.tname LIKE '%Hoffman'; 
+0

非常感謝,我只能接受一個答案,並且與@ Miguelo的答案一起,因爲他包含了程序限制,但這看起來同樣可以接受! – Timmy

+0

@Timmy。沒問題。我不確定這是否是一項要求,並且因爲您在描述中沒有提及它,所以我沒有包括它。 –

2

您可以使用連接來解決這個問題,而不是子查詢

SELECT * FROM Public."Student" s 
join Public.Enrolled e on (s.sid= e.id) 
join Public.Class c on (c.ccode = e.ccode) 
join Public.Tutor t on (c.tid = t.tid) 
WHERE s.programme='IT' and t.tname like '%Hoffman' 
+0

非常感謝! – Timmy

+0

@Timmy另外,無論如何,正確的基於子查詢的查詢可能只會被優化器轉換爲上述基於連接的查詢。它可以的時候更喜歡扁平化子查詢。一般來說,只有當你不能完成你所需要的連接時,你才需要子查詢。 –