SQL語句中過濾條件放在on、where、having的區別和聯繫
摘要:SQL語句中,過濾條件放在不同篩選器on、where和having的區別和聯繫。
綜述
在《SQL語句中過濾條件放在on和where子句中的區別和聯繫》中,介紹了多表關聯SQL語句中,過濾條件放在on和where子句中的區別——inner join中沒區別,外連接就不一樣。本文在此基礎上,介紹on、where和having三類子句的區別和聯繫。
區別和聯繫
在寫SQL語句的時候,我們經常會用到各種表連接(left join、right join、inner join和 full join等),還有各種分組聚合函數(sum、min、max、avg和count等)。那麼我們在寫連接操作SQL的時候,對於不同的過濾條件是放在 ON 子句,還是代表分組操作的 having 子句,抑或 where子句中呢?我們先看一下三種條件關鍵字的執行順序:
on > where > 聚合函數 > having
詳細的來講,就是:
步驟一、根據on篩選器生成生成臨時表。此時的臨時表會因為left join或right join的特性而一定帶有主表的記錄,也就是主表的記錄不會被 on 條件過濾掉。
步驟二、根據where篩選器過濾臨時表。因為臨時表已經生成完畢,根據where條件過濾時主表記錄也會被過濾。
步驟三、聚合函數進行運算。
步驟四、 聚合函數運算完畢,having子句生效,對運算完畢的臨時表進行過濾 ,生成最終的結果表。
三個篩選器on、where和having都可以加條件,on是最先執行,where次之,having最後。有時候如果這先後順序不影響中間結果的話,那最終結果是相同的。但因為on是先把不符合條件的記錄過濾後才進行統計,它就可以減少中間運算要處理的數據,按理說應該速度是最快的。
了解了上述執行過程後,我們來聊聊應該把過濾條件放在哪,即如何使用on、where和having篩選器。下面是一些基礎的選擇標準,供各位參考:
所有的連接條件都必需要放在ON子句。
如果在表關聯後需要保留主表的所有記錄,不論有沒有相匹配的從表記錄,那麼我們就應該將過濾條件放在 on 中。
如果過濾條件需要在聚合函數運算完畢之後才能確定,比如我們想要找出平均分數大於60分的班級,那麼就必須等待分組聚合函數執行完畢才能進行過濾,那這個過濾條件肯定就是放在having中了,因為where生效的時候聚合函數還沒有進行運算。
如果過濾條件不依賴聚合函數,只是想要符合條件的部分記錄,而且沒有要求保留主表的全部記錄,那麼我們就應該放在where子句中。當然,如果表關聯是採用inner join的話,因為沒有主從表的關係,所以放在 where 和 on 中是一樣的。
就執行效率來看:因為on生效最早,所以放在on中應該最快,其次是where,最後是having。
結束語
以上就是這篇文章的全部內容了,希望本文對大家的學習或者工作具有一定的參考和學習價值;如果有疑問,大家可以在評論區留言交流,也希望大家多多點贊關注。謝謝大家對樓蘭胡楊的支援!