2014-04-14 18 views
0

我有三個相關的表(學生,班級,招生)(一個學生可以有多個註冊,一個班級可以有多個註冊),我需要從中選擇所有註冊班級的學生(x,y,z),但不在類(a,b,c)中。我怎樣才能構建我的查詢來實現這一目標?SQL Select:同一個表的子集

+0

無法給出一個準確的信息,而不架構 – smk

回答

1

我不同意我們需要更多的信息才能說實話。像這樣的東西應該工作。另一種方法是使用關鍵字MINUS來獲得第一個查詢(類x,y和z中的學生)的所有結果,但第二個查詢(類a,b和c中的學生)的結果除外。

選擇所有x,y和z類以及類別a,b和c中的所有類的所有學生。

SELECT * FROM Students s 
WHERE EXISTS (SELECT * FROM Enrollment 
    WHERE studentId = s.StudentId AND ClassId = 'x') 
AND EXISTS (SELECT * FROM Enrollment 
    WHERE studentId = s.StudentId AND ClassId = 'y') 
AND EXISTS (SELECT * FROM Enrollment 
    WHERE studentId = s.StudentId AND ClassId = 'z') 
AND NOT EXISTS (SELECT * FROM Enrollment 
    WHERE studentId = s.StudentId AND ClassId IN ('a', 'b', 'c') 
+0

大,這並獲得成功。一個問題,但......爲什麼你爲每個ClassId創建一個WHERE EXISTS而不是像在WHERE NOT EXISTS中那樣使用IN(x,y,z)? – JEJ

+0

因爲如果我這樣做了,它會給予任何類x,y或z中的學生,而不是所有的類x,y和z。 – wvdz

1

應該DDL(只引進名):

create table student (s_id numeric, name varchar); 
create table class (c_id numeric, name varchar); 
create table enrollment (s_id numeric, c_id numeric); 
  1. 學生選擇id,而不是在A,B或C

    select s_id from enrollments where c_id not in 
        (select c_id from class where name in ('a', 'b', 'c'); 
    
  2. 選擇學生的IDS x,y或z

    select s_id from enrollments where c_id in 
        (select c_id from class where name in ('x', 'y', 'z'); 
    
  3. 結合起來

    select * from students where 
        s_id in (select s_id from enrollments where c_id in 
         (select c_id from class where name in ('x', 'y', 'z') and 
        s_id not in (select s_id from enrollments where c_id in 
         (select c_id from class where name in ('a', 'b', 'c');