淺析SQL having子句、如何使用having子句及where子句與having子句的區別


一、SQL having子句簡介

  在 SQL 中增加 HAVING 子句原因是,WHERE 關鍵字無法與聚合函數一起使用。

  HAVING 子句可以讓我們篩選分組后的各組數據。

1、SQL HAVING 語法:operator 代表運算操作符、aggregate_function 代表聚合函數

SELECT column_name, aggregate_function(column_name) FROM table_name WHERE column_name operator value GROUP BY column_name HAVING aggregate_function(column_name) operator value;

2、示例:

下面是選自 "Websites" 表的數據: +----+--------------+---------------------------+-------+---------+
| id | name         | url                       | alexa | country |
+----+--------------+---------------------------+-------+---------+
| 1  | Google       | https://www.google.cm/    | 1     | USA     |
| 2  | 淘寶          | https://www.taobao.com/   | 13    | CN      |
| 3  | 菜鳥教程      | http://www.runoob.com/    | 4689  | CN      |
| 4  | 微博          | http://weibo.com/         | 20    | CN      |
| 5  | Facebook     | https://www.facebook.com/ | 3     | USA     |
| 7  | stackoverflow | http://stackoverflow.com/ |   0 | IND     |
+----+---------------+---------------------------+-------+---------+
 下面是 "access_log" 網站訪問記錄表的數據: mysql> SELECT * FROM access_log; +-----+---------+-------+------------+
| aid | site_id | count | date       |
+-----+---------+-------+------------+
|   1 |       1 |    45 | 2016-05-10 |
|   2 |       3 |   100 | 2016-05-13 |
|   3 |       1 |   230 | 2016-05-14 |
|   4 |       2 |    10 | 2016-05-14 |
|   5 |       5 |   205 | 2016-05-14 |
|   6 |       4 |    13 | 2016-05-15 |
|   7 |       3 |   220 | 2016-05-15 |
|   8 |       5 |   545 | 2016-05-16 |
|   9 |       3 |   201 | 2016-05-17 |
+-----+---------+-------+------------+
9 rows in set (0.00 sec)

(1)現在我們想要查找總訪問量大於 200 的網站。我們使用下面的 SQL 語句:

SELECT Websites.name, Websites.url, SUM(access_log.count) AS nums FROM (access_log INNER JOIN Websites ON access_log.site_id=Websites.id) GROUP BY Websites.name HAVING SUM(access_log.count) > 200;

(2)現在我們想要查找總訪問量大於 200 的網站,並且 alexa 排名小於 200。我們在 SQL 語句中增加一個普通的 WHERE 子句:

SELECT Websites.name, SUM(access_log.count) AS nums FROM Websites INNER JOIN access_log ON Websites.id=access_log.site_id WHERE Websites.alexa < 200 GROUP BY Websites.name HAVING SUM(access_log.count) > 200;

二、Having子句和Where子句

1、區別:

(1)where 不能放在GROUP BY 后面

(2)HAVING 是跟GROUP BY 連在一起用的,放在GROUP BY 后面,此時的作用相當於WHERE

(3)WHERE 后面的條件中不能有聚集函數,比如SUM(),AVG()等,而HAVING 可以

  where 和 having 都是對查詢結果的一種篩選,說的書面點就是設定條件的語句。

2、聚合函數:聚合函數有時候也叫統計函數,它們的作用通常是對一組數據的統計,比如說求最大值,最小值,總數,平均值( MAX,MIN,COUNT, AVG)等。

  這些函數和其它函數的根本區別就是它們一般作用在多條記錄上。簡單舉個例子:SELECT SUM(sal) FROM emp,這里的SUM作用是統計emp表中 sal(工資)字段的總和,結果就是該查詢只返回一個結果,即工資總和。

  通過使用GROUP BY 子句,可以讓 SUM 和 COUNT 這些函數對屬於一組的數據起作用。

3、where子句:where 子句僅僅用於從 from 子句中返回的值,from 子句返回的每一行數據都會用 where 子句中的條件進行判斷篩選。

  where子句中允許使用比較運算符(>,<,>=,<=,<>,!=|等)和邏輯運算符(and,or,not)。

4、having子句:having子句通常是與 order by 子句一起使用的。因為 having 的作用是對使用 group by 進行分組統計后的結果進行進一步的篩選

-- 舉個例子:現在需要找到部門工資總和大於10000的部門編號?

-- 第一步:先按部門分組
select deptno,sum(sal) from emp group by deptno; -- 篩選結果如下:
DEPTNO   SUM(SAL) ------ ----------
    30       9400
    20      10875
    10       8750
-- 可以看出我們想要的結果了。不過現在我們如果想要部門工資總和大於10000的呢? -- 那么想到了對分組統計結果進行篩選的having來幫我們完成。

-- 第二步:利用 having子句篩選
select deptno,sum(sal) from emp group by deptno having sum(sal)>10000; -- 篩選結果如下:
DEPTNO   SUM(SAL) ------ ----------
    20      10875

-- 當然這個結果正是我們想要的。

5、下面我們通過 where 子句和 having 子句的對比,更進一步的理解它們。

  在查詢過程中聚合語句 (sum,min,max,avg,count) 要比 having 子句優先執行,簡單的理解為只有有了統計結果后我才能執行篩選。

  where子句在查詢過程中執行優先級別優先於聚合語句(sum,min,max,avg,count),因為它是一句一句篩選的。

  HAVING子句可以讓我們篩選成組后的對各組數據篩選,而WHERE子句在聚合前先篩選記錄。

-- 如現在我們想要部門號不等於10的部門並且工資總和大於8000的部門編號? -- 我們這樣分析: -- 1、通過where子句篩選出部門編號不為10的部門, -- 2、然后在對部門工資進行統計, -- 3、然后再使用having子句對統計結果進行篩選。

select deptno,sum(sal) from emp where deptno!='10' group by deptno having sum(sal)>8000; -- 篩選結果如下:
DEPTNO   SUM(SAL) ------ ----------
    30       9400
    20      10875

  簡單總結執行優先級就是:where 子句   >  聚合語句   >  having 子句

  簡單的說就是:先篩選之后再條件分組,就用 where;先分組之后再條件篩選,就用 having

6、異同點

  它們的相似之處就是定義搜索條件,不同之處是 where 子句為單個篩選,而 having 子句與組有關,而不是與單個的行有關。

  理解 having 子句和 where 子句最好的方法就是基礎 select 語句中的那些句子的處理次序:where 子句只能接收 from 子句輸出的數據,而 having 子句則可以接受來自 group by,where 或者 from 子句的輸入。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM