1. 程式人生 > 實用技巧 >on、where、having的區別和關係

on、where、having的區別和關係

三種條件關鍵字的執行順序如下:

on > where > 聚合函式 > having

ON、WHERE、HAVING的主要差別是其子句中限制條件起作用時機引起的,

ON是在生產臨時表之前根據條件篩選記錄,

WHERE是從生產的臨時表中篩選資料,

而HAVING是對臨時表中滿足條件的資料,進行計算分組之後,通過HAVING限制語句篩選分組,返回結果是滿足HAVING子句限制的分組。

(Where分組前過濾,不能使用聚合函式;Having 分組之後過濾,可以使用聚合函式,HAVING不能單獨出現,只能出現在GROUP BY子句之中)

選擇的標準:

1. 如果我們的過濾條件需要在聚合函式運算完畢之後才能確定,比如我們想要找出平均分數大於60分的班級,那麼就必須等待分組聚合函式執行完畢才能進行過濾,那這個條件肯定就是放在having中了,因為where生效的時候聚合函式還沒有進行運算呢。

2. 如果我們的過濾條件不需要依賴聚合函式,只是想要表關聯之後的結果表中符合條件的部分,而沒有要求保留主表的全部記錄,那麼我們就應該放在where條件中,當然,如果表關聯是採用inner join的話,因為沒有主從表的關係,所以放在 where 和 on 中是一樣的。

3. 如果我們的過濾條件不需要依賴聚合函式,並且在表關聯後需要保留主表的所有記錄,不論有沒有相匹配的從表記錄,那麼我們就應該將過濾條件放在 on 中。

就效能來看:

因為on生效最早,所以放在on中應該最快,其次是where,最後是having。

on和where的區別

資料庫在通過連線兩張或多張表來返回記錄時,都會生成一張中間的臨時表,然後再將這張臨時表返回給使用者。
在使用leftjion時,on和where條件的區別如下:
1、on條件是在生成臨時表時

使用的條件,它不管on中的條件是否為真,都會返回左邊表中的記錄。
2、where條件是在臨時表生成好後,再對臨時表進行過濾的條件。這時已經沒有leftjoin的含義(必須返回左邊表的記錄)了,條件不為真的就全部過濾掉。

join過程可以這樣理解:首先兩個表做一個笛卡爾積,on後面的條件是對這個笛卡爾積做一個過濾形成一張臨時表,如果沒有where就直接返回結果,如果有where就對上一步的臨時表再進行過濾。

下面看實驗:

先準備兩張表:

先執行inner join:

select * from person p inner join account a on p.id=a.id and p.id!=
4 and a.id!=4;

select * from person p inner join account a on p.id=a.id where p.id!=4 and a.id!=4;

結果沒有區別,前者是先求笛卡爾積然後按照on後面的條件進行過濾,後者是先用on後面的條件過濾,再用where的條件過濾。

再看看左連線left join

select * from person p left join account a on p.id=a.id and p.id!=4 and a.id!=4;

select * from person p left join account a on p.id=a.id where p.id!=4 and a.id!=4;

在on為選擇條件時,id為4的記錄還在,這是由left join的特性決定的,使用left join時on後面的條件只對右表有效(可以看到右表的id=4的記錄為NULL)

在where為選擇條件時,where過濾掉了左表中的內容。

記住:所有的連線條件都必需要放在ON後面,不然前面的所有LEFT,和RIGHT關聯將作為擺設,而不起任何作用。

參考部落格:https://blog.csdn.net/u013468917/article/details/61933994