oracle中右表有過濾條件的left outer join
oracle中left outer join就是以左表作為基表來進行連線操作,連線的結果中一定會涵蓋基表中所有的列,即使有某些列與右表找不到匹配關係。如下分別是city表和stds表中的資料截圖:
現在執行以下語句:
select city.name,stds.sid,stds.sname from city left outer join stds on city.id=stds.cid;
其結果截圖如下,即使沒有湖南的學生,湖南那一項仍然在結果集中,因為city表是基表,它的每一項都會在結果集中。
現在我們假如要獲取sid不等於4的情況的左連線結果,那麼有兩種選擇,一種是在on中新增條件限制,一種是在where中新增條件限制,我們現在來測試兩種結果是否相同。
先執行在on中新增條件,執行以下語句:
select city.name,stds.sid,stds.sname from city left outer join stds on city.id=stds.cid and stds.sid!=4;
執行結果和執行計劃如下:
檢視執行結果,我們可以看到結果中仍然包括了基表,也就是city表中的所有行。然後再檢視執行計劃,可以看到先是ACCESS內層的STDS表,並且加上filter(SID<>4),然後再和外層的CITY表進行左連線操作,所以仍然可以保證city表中每一行都在結果集中。
再執行where中新增條件,執行語句如下:
select city.name,stds.sid,stds.sname from city left outer join stds on city.id=stds.cid where stds.sid!=4
其執行結果如下圖所示:
由於sql的執行順序是先from得到源資料,再where篩選資料,最後select投影資料。先join之後,結果集中應該有
sid為null的結果項,但是由於oracle中任何與null做=或者!=等邏輯判斷得到的結果都是unknown,歸為false,
所以sid為null的項最終會被剔除掉,而sid=4的資料項也會被剔除掉,所以才出現了上述結果。
下面是做的一個null做等於判斷和不等於判斷的截圖:
所以如果做左外連線時,如果右錶帶條件約束,它把條件約束放在on中和where中得到的結果是不一樣的,這時需要根據自己的需求進行選擇。