SQL join中on與where區別

FrankYou發表於2016-08-16

本文導讀:

資料庫在通過連線兩張或多張表來返回記錄時,都會生成一張中間的臨時表,然後再將這張臨時表返回給使用者。例如在使用left jion時,on條件是在生成臨時表時使用的條件,它不管on中的條件是否為真,都會返回左邊表中的記錄where條件是在臨時表生成好後,再對臨時表進行過濾的條件。

on、where、having的區別

1、on、where、having這三個都可以加條件的子句中,on是最先執行,where次之,having最後。有時候如果這先後順序不影響中間結果的話,那最終結果是相同的。但因為on是先把不符合條件的記錄過濾後才進行統計,它就可以減少中間運算要處理的資料,按理說應該速度是最快的。

2、where應該比having快點的,因為它過濾資料後才進行sum,所以having是最慢的。但也不是說having沒用,因為有時在步驟3還沒出來都不知道那個記錄才符合要求時,就要用having了。

3、在兩個表聯接時才用on的,所以在一個表的時候,就剩下where跟having比較了。在這單表查詢統計的情況下,如果要過濾的條件沒有涉及到要計算欄位,那它們的結果是一樣的,只是where可以使用rushmore技術,而having就不能,在速度上後者要慢。

4、如果要涉及到計算的欄位,就表示在沒計算之前,這個欄位的值是不確定的,根據上篇寫的工作流程,where的作用時間是在計算之前就完成的,而having就是在計算後才起作用的,所以在這種情況下,兩者的結果會不同。

5、在多表聯接查詢時,on比where更早起作用。系統首先根據各個表之間的聯接條件,把多個表合成一個臨時表後,再由where進行過濾,然後再計算,計算完後再由having進行過濾。由此可見,要想過濾條件起到正確的作用,首先要明白這個條件應該在什么時候起作用,然後再決定放在那裡

 

例項說明

 

1、假設有兩張表:


表1:tab1
 

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的過程:

 

1、中間表on條件: tab1.size = tab2.size

 

 tab1.id   tab1.size   tab2.size   tab2.name

 1  10  10  AAA

  2  20  20 BBB

  2 20 20 CCC

  3 30 (null) (null)


2、再對中間表過濾where 條件:tab2.name=’AAA’

 

tab1.id   tab1.size   tab2.size   tab2.name
1   10  10   AAA

 

第二條SQL的過程

中間表on條件: tab1.size = tab2.size and tab2.name=’AAA’(條件不為真也會返回左表中的記錄)

tab1.id tab1.size tab2.size tab2.name
1  10  10  AAA
2  20  (null)  (null)
3  30  (null)  (null)

 

2、例項2詳細說明

 

SQL語句如下:

SELECT *
FROM 表1
LEFT JOIN 表2 ON 表1.id = 表2.id AND 表2.Name != 'ff'
WHERE 表1.NAME != 'aa'

步驟1:返回笛卡爾積(SELECT * FROM 表1 CROSS JOIN 表2)

步驟2:應用ON篩選器(當前的條件為 表1.id = 表2.id AND 表2.Name != 'ff')

步驟3:新增外部行

這一步只對OUTER JOIN起作用,如果是LEFT JOIN會以左邊的表為保留表,如果是RIGHT JOIN會以右邊的表為保留表。所謂外部行是指,保留表中的行。即使第二步的ON過濾掉了一些行,在這一步,會根據保留表新增第二步過濾掉的行。當前的例子,不存在這種情況。

步驟4.應用WHERE篩選器(當前是Name != ‘aa’)過濾前三步所生成虛擬表的資料。

 

總結:

1、如果SQL用的是Left Join ,On後面的條件對Left的表沒有作用,只對Right的表有過濾作用,Where語句可以對Left的表有過濾作用

2、如果SQL用的是Right Join ,On後面的條件對Right的表沒有作用,只對Left的表有過濾作用,Where語句可以對Right的表有過濾作用

 

相關文章