sql多表關聯查詢使用JOIN..ON與where的優化場景
先說明原因:
關鍵字: on
資料庫在通過連線兩張或多張表來返回記錄時,都會生成一張中間的臨時表,然後再將這張臨時表返回給使用者。
在使用left jion時,on和where條件的區別如下:
1、 on條件是在生成臨時表時使用的條件,它不管on中的條件是否為真,都會返回左邊表中的記錄。
2、where條件是在臨時表生成好後,再對臨時表進行過濾的條件。這時已經沒有left join的含義(必須返回左邊表的記錄)了,條件不為真的就全部過濾掉。
假設有兩張表:
表1:tab2
id | size |
1 | 10 |
2 | 20 |
3 | 30 |
表2:tab2
size | name |
10 | AAA |
20 | BBB |
20 | CCC |
兩條SQL:
1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’
2、select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’)
第一條SQL的過程:
|
第二條SQL的過程:
|
實戰練習
1.首先先建立兩個表
create table table1 ( mon varchar2(14), dep number(4), yj number(4) ) insert into table1 values ('一月份',1,10); insert into table1 values ('一月份',2,10); insert into table1 values ('一月份',3,5); insert into table1 values ('二月份',2,8); insert into table1 values ('二月份',4,9); insert into table1 values ('二月份',3,8); create table table2 ( dep number(4), dname varchar2(30) ) insert into table2 values(1,'國內業務一部'); insert into table2 values(2,'國內業務二部'); insert into table2 values(3,'國內業務三部'); insert into table2 values(4,'國際業務部');
2.要求查出每個部門一月份,二月份的業績
查出結果如下
3 用以下where語句增加最後的過濾條件在特定場景下肯定是可以的 (但是鑑於這裡是要1~4月全部展示,所以where子句還是不符合條件,在這裡列出是為了說明where是在on條件執行之後增加過濾條件)
select t0.dep as dep,t0.dname as 部門名稱 , t1.yj as 一月份業績 , t2.yj as 二月份業績 from table2 t0 left join table1 t1 on t0.dep=t1.dep left join table1 t2 on t0.dep=t2.dep where t1.mon='一月份' and t2.mon='二月份' order by t0.dep
4. 接下來把where條件去掉看查出來的資料有10條,可以發現這其中沒有 t1.mon='一月份' and t2.mon='二月份'的限定條件,
table2表的國際業務一部 (dep=1)與 table1表的一月份(dep=1)的業績為10(yj=10) 匹配2次,分別匹配出一條一月份的業績和二月份的業績 ,因為國際業務一部二月份麼有業績,所以這明顯是錯誤的匹配 (增加了額外的中間表數量)
5. 如果能在匹配之前先對應加上t1.mon='一月份' 或者 t2.mon='二月份'的限定條件,如果沒有滿足限定條件,後面的t0.dep=t1.dep就不會執行,這樣就會至少在中間表中會少一條資料, 假如再使用where過濾就會減少過濾運算元量
select t0.dep as dep,t0.dname as 部門名稱 , t1.yj as 一月份業績 , t2.yj as 二月份業績 from table2 t0 left join table1 t1 on t1.mon='一月份' and t0.dep=t1.dep left join table1 t2 on t2.mon='二月份' and t0.dep=t2.dep order by t0.dep
參考文章:https://www.cnblogs.com/wlzhang/p/4532587.html
https://www.cnblogs.com/lykbk/p/aefweere45454545454.html