2013-07-07 73 views
3

我在OUTER JOIN的以下SQL(可能微不足道)中感到困惑。
我有2個小桌emp和對員工及其部門的記錄deptno即。他們的關係顯然是1-N(但這是無關緊要的)。
我正在嘗試使用外連接來查找沒有員工在那裏工作的部門。所以我認爲正確的解決方案是OUTER JOIN
如果我做到以下幾點:爲什麼這個左外連接會產生錯誤的結果?

select d.deptno as d_deptno, e.deptno as e_deptno 
from dept d left outer join emp e 
on d.deptno = e.deptno;  

我得到:

d_deptno e_deptno 
10,   10 
10,   10 
10,   10 
20,   20 
20,   20 
20,   20 
20,   20 
20,   20 
30,   30 
30,   30 
30,   30 
30,   30 
30,   30 
30,   30 
40,   null  

好了,所以我想我需要的僅僅是最後一排,所以我只需要如下修改我的查詢:

select d.deptno as d_deptno, e.deptno as e_deptno 
from dept d left outer join emp e 
on d.deptno = e.deptno and e.deptno is null; 

即我加了and e.deptno is null。出於某種原因,如果我沒有e_deptno is null查詢無法解析(爲什麼?)
但我得到的結果如下!

d_deptno e_deptno 
10,  null 
20,  null 
30,  null 
40,  null 

爲什麼我會得到這些結果?我對OUTER JOIN有什麼誤解?

+0

你應該把在where子句'那裏e.deptno是null' – chetan

+0

此外,您不能在條件中使用別名第二個條件。 – chetan

+0

@chetan:所以我不能'加入和或等'? – Jim

回答

3

條件e.deptno is null需要是where子句中:

select d.deptno as d_deptno, e.deptno as e_deptno 
from dept d left outer join emp e 
on d.deptno = e.deptno 
where e.deptno is null 

這是因爲on子句使用規定爲準則,以加入行從一個表到另一個條件 - 因此這只是鏈接到emp的記錄空值爲deptno,同時deptnodept記錄匹配。

由於這些標準是相互排斥的,查詢永遠不會成功地鏈接到一個emp記錄,所以外連接保證了空值的emp返回的值。

where子句應用後的連接條件 - 所以移動is null條件進where子句確保僅dept記錄沒有匹配emp記錄被選擇。

e_deptno is null是不是在這個查詢無論是在on條款或where條款有效,因爲e_deptno是SELECT子句中只定義了(在onwhere任何分組已經應用後) - 它很可能是有效的在一個條款(在MySQL中),但是。

+0

那麼我的'on ...和'版本是做什麼的?還有任何想法爲什麼'e_deptno'不被接受爲查詢的一部分? – Jim

+0

@Jim - 查看我更新的答案。 –

+0

+1。 '所以它只會鏈接到具有null deptno的emp記錄,並且同時有一個與dept記錄相匹配的deptno'你的意思是來自'emp'的記錄具有匹配的'e.deptno' **和** emp記錄具有'deptno '作爲'null'對嗎? – Jim

相關問題