假設有兩個表a、b
使用on
Select * from a left join b on b.col = a.col and b.col2 = ‘aa’
使用 where
Select * from a left join b on b.col = a.col where b.col2 = ‘aa’ and b.col2 is null
// b.col2 is null作用是防止因b表中沒有匹配數據,照成a表原有記錄無法返回的問題
分析
1、on條件是在生成臨時表時使用的條件,它不管on中的條件是否為真,都會返回左邊表中的記錄。
2、where條件是在臨時表生成好後,再對臨時表進行過濾的條件。這時已經沒有left join的含義(必須返回左邊表的記錄)了,條件不為真的就全部過濾掉。
語句測試
set serveroutput on ; -- 必須運行,否則打印結果無法顯示
declare
I Number;
Starttime Timestamp;
Endtime Timestamp;
Begin
select current_timestamp(5) into starttime from Dual;
I := 1;
While I<=10000 Loop
dbms_output.put_line(i);
Execute Immediate ' '; --此處放入sql語句
i := i+1;
End Loop;
Select Current_Timestamp(5) Into Endtime From Dual;
dbms_output.put_line('10000條語句運行時間為(毫秒):' || (endtime - starttime)); --打印一個Interval類型數據,顯示時間差
end;
測試結果
On語句, 10000條語句運行時間為(毫秒):+000000000 00:00:01.032850000
Where 語句 10000條語句運行時間為(毫秒):+000000000 00:00:01.013420000
結論
Where語句的性能優於on語句
其實sql語句的運行效率也可以通過查詢oracle的系統視圖來查看,但時間關系今後再研究了。
附
在C#中使用linq進行查詢
// 寫得比較倉促,見諒了
var reList = from DataRow a in dtA.Rows
join DataRow b in dtB.Rows on
new {t = a["col"], l=’aa’}
equals
new {t = b["col"], l = b["col2"] }
into rightRow from rw in rightRow.DefaultIfEmpty()
select new
{
Col1 = a["col"],
Col2 = rw["col2"]
};
在linq中使用into rightRow from rw in rightRow.DefaultIfEmpty()可以保證查詢類型left outer join的效果,如果left join中有多個查詢條件,使用new兩個對象進行比較即可。