having子句與where子句

2020-10-13 13:00:24

1.相同點
都是對記錄進行篩選
2.不同點
2.1 where 不能放在group by後面

2.2 having 是跟group by連在一起用的,放在group by 後面,此時的作用相當於where

2.3 where 後面的條件中不能有聚集函數,比如SUM(),AVG()等,而HAVING可以。

一、where子句

where子句:where子句僅僅用於從from子句中返回的值,from子句返回的每一行資料都會用where子句中的條件進行判斷篩選,where子句中允許使用比較運運算元和邏輯運運算元

二、having子句

having子句:having子句通常是與group by子句一起使用的,因為having的作用是對使用group by 進行分組統計後的結果進行進一步的篩選。
三、下面通過where子句和having子句的對比,更進一步的理解他們

在查詢過程中聚合函數(SUM,MIN,MAX,AVG,COUNT)要比having子句優先執行,簡單的理解為只有有了統計結果後我才能執行篩選。where子句在查詢過程中執行優先順序別優先於聚合函數(SUM,MIN,MAX,AVG,COUNT),因為他是一句一句篩選的,HAVING子句可以讓我們篩選成組後的對各組資料篩選。而WHERE子句在聚合前篩選記錄,如:現在我們想要部門號不等於10的部門並且工資總和大於8000的部門編號?

分析:通過where子句篩選除部門編號不為10的部門,然後對部門工資進行統計,然後使用having子句對統計結果進行篩選。

 select deptno,sum(sa1) from emp

    where deptno<>'10'  group by deptno

    having sum(sa1)>8000;

FAQ:1.既然where 和having 都可以對記錄進行篩選 那麼為什麼不直接用having?
HAVING 只會在檢索出所有記錄之後才對結果集進行過濾. 這個處理需要排序,總計等操作. 如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷。
2.為什麼group by 之後不可以用where 子句 ?
答:1).首先 我們看一下資料庫的書寫順序 以及 執行順序
書寫順序:select … from … where … group by … having … order by … limit …
好的 我們看到 書寫順序應該是where 在 group by 之前 ,你要問我為啥,
我會說甲魚的屁股–規定。。。

2).然後我們再看一下執行順序
執行順序:from–>where–>select–>group by–>having–>order by–>limit…
我們可以看到 where 子句 是在 group by 之前執行的 也就是說 我們先找到表,再根據where子句的條件進行篩選 ,再進行查詢操作 ,之後再進行分組等操作 ,所以說 group by 是對 基於where 條件查詢的結果進行操作。 having子句是會在分組後對分組形成的結果進行過濾。

也正是因為執行順序所以where中可以使用表別名但是不能使用列別名 ,而having中可以使用表別名 也可以使用列別名。

小結:where子句只能接受from子句輸出的資料,而having子句則可以接受來自group by ,where或者from子句的輸入。

參考了很多大佬的文章 ,侵刪。
以上。