2016-02-28 47 views
2

我有這些表:SQL排除行,而不子查詢

PERSON    COURSE    PERSON_COURSE 
+----+----------+ +----+----------+ +------+------+ 
| ID | Name  | | ID | Name  | | P_ID | C_ID |  
+----+----------+ +----+----------+ +------+------+ 
| P1 | Person 1 | | C1 | Course 1 | | P1 | C1 | 
| P2 | Person 2 | | C2 | Course 2 | | P1 | C2 | 
| P3 | Person 3 | | C3 | Course 3 | | P3 | C2 | 
+----+----------+ +----+----------+ | P3 | C3 | 
              +------+------+ 

,我想選擇所有不參加課程C1人。

所以我使用的是:

select p.id 
from person p 
where p.id not in (
    select pc.p_id 
    from person_course pc 
    where pc.c_id != 'C1') 

現在,我想知道是否有可能獲得相同的結果,而無需使用子查詢。

回答

3

一個選項是左連接,試圖與課程相匹配的人和我只包括沒有匹配的人;

​​3210

An SQLfiddle to test with

1

我想選擇所有不參加課程的人C1

你可以使用聚合:

SELECT P.ID, P.NAME 
FROM PERSON P 
LEFT JOIN PERSON_COURSE PC 
    ON P.ID = PC.P_ID 
GROUP BY P.ID, P.NAME 
HAVING SUM(CASE WHEN PC.C_ID = 'C1' THEN 1 ELSE 0 END) = 0; 

LiveDemo

輸出:

╔════╦══════════╗ 
║ ID ║ Name ║ 
╠════╬══════════╣ 
║ P2 ║ Person 2 ║ 
║ P3 ║ Person 3 ║ 
╚════╩══════════╝ 
1

我只想指出,你可以使用子查詢來做到這一點,但它不是問題中的問題。相反:

select p.id 
from person p 
where p.id not in (select pc.p_id 
        from person_course pc 
        where pc.c_id = 'C1' 
---------------------------------^ 
       ); 

(雖然我更喜歡NOT EXISTS這個邏輯,我保持這個類似於你的邏輯越好。)

小心雙重否定。