2016-11-10 63 views
2

在我們的web應用,員工可以在同一時間執行一個或更多的就業機會,所以數據庫的結構是這樣的:如何選擇除匹配連接的記錄以外的記錄?

http://rextester.com/VTFND62465

tma_employee

emp_id | emp_name 
-------|--------- 
1  | BOB 
2  | MAX 
3  | SALLY 

tma_job

job_id | job_name 
-------|--------- 
1  | DEV 
2  | SALES 
3  | MGMT 

員工與工作之間的關係表tma_employee_job

emp_id | job_id 
-------|------- 
1  | 1 
1  | 2 
2  | 2 
2  | 3 
3  | 3 
3  | 1 

鑑於這種結構,很容易選擇哪個執行一個或多個特定作業的所有員工:

SELECT DISTINCT E.* 
FROM tma_employee E 
JOIN tma_employee_job EJ USING (emp_id) 
JOIN tma_job J USING (job_id) 
WHERE J.job_name = 'DEV'; 

但是,我怎麼可以選擇做執行所有員工工作?

我試圖反轉這樣的條件:

SELECT DISTINCT E.* 
FROM tma_employee E 
JOIN tma_employee_job EJ USING (emp_id) 
JOIN tma_job J USING (job_id) 
WHERE J.job_name != 'DEV'; 

然而,這並不工作,因爲,例如,BOB也對銷售工作,這是從DEV不同,所以員工BOB從發現以上查詢。

我還發現,這個工程:

SELECT DISTINCT E.* 
FROM tma_employee E 
WHERE E.emp_id NOT IN (
    SELECT EJ.emp_id 
    FROM tma_employee_job EJ 
    JOIN tma_job J USING (job_id) 
    WHERE J.job_name = 'DEV' 
); 

但是,它要求我使用子查詢,這是我想避免的,因爲主查詢是由基於該功能內置它接收的參數從SELECT E.* FROM tma_employee E開始,然後添加所有的JOINS和子句。

是否可以獲得使用子查詢的查詢的同樣結果,同時堅持簡單的JOINS?

回答

3

SQL DEMO無子查詢:

SELECT E.emp_id, E.emp_name 
FROM tma_employee E 
LEFT JOIN tma_employee_job EJ USING (emp_id) 
LEFT JOIN tma_job J ON J.job_id = EJ.job_id 
GROUP BY E.emp_id, E.emp_name 
HAVING COUNT(CASE WHEN job_name = 'DEV' THEN 1 END) = 0; 
+0

我認爲你釘了它! –

+0

這似乎工作正常,很容易與查詢生成器功能管理...我會盡快嘗試。 –

1

試試這個:

SELECT DISTINCT E.* 
FROM tma_employee E 
LEFT JOIN (
    SELECT EJ.emp_id 
    FROM tma_employee_job EJ 
    JOIN tma_job J USING (job_id) 
    WHERE J.job_name = 'DEV' 
) T ON E.emp_id = T.emp_id 
WHERE T.emp_id IS NULL 
+0

的作品,但仍然使用子查詢,我想避免 –

+0

@MatteoTassinari這心不是一個真正的子查詢這是派生表。不應該是任何性能問題。 –

+0

@JuanCarlosOropeza你說得對,我這裏的問題不是性能,而是一個用於創建查詢字符串的函數,它已經足夠複雜了......它也可能是我無法按照我喜歡的方式來解決這個問題。 –