為聚合結(jié)果指定條件
如果想要從 GROUP BY 分組中進(jìn)行篩選的話,不是用 WHERE 而是使用 HAVING 來進(jìn)行聚合函數(shù)的篩選。
比如之前問過的問題,如何從商品分類匯總中找到條數(shù)為2的商品種類呢?

1. HAVING子句
HAVING 子句寫法:
SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
GROUP BY <列名1>, <列名2>, <列名3>, ……
HAVING <分組結(jié)果對應(yīng)的條件>
HAVING 子句必須寫在GROUP BY 子句之后,其在DBMS 內(nèi)部的執(zhí)行順序也排在GROUP BY 子句之后。
使用HAVING 子句時SELECT 語句的順序
SELECT → FROM → WHERE → GROUP BY → HAVING
1.1使用HAVING進(jìn)行分組篩選
接下來就讓我們練習(xí)一下HAVING 子句吧。例如,針對按照商品種類進(jìn)行分組后的結(jié)果,指定“包含的數(shù)據(jù)行數(shù)為2 行”這一條件的SELECT 語句。
示例:查詢商品分類條數(shù)匯總并將條數(shù)為2的商品提取出來
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type
HAVING COUNT(*) = 2;
執(zhí)行結(jié)果:
product_type | count
-------------+------
衣服 | 2
辦公用品 | 2
1.2 對比不使用 HAVING 的情況下 SQL 語句執(zhí)行的情況
示例:不使用HAVING進(jìn)行條件篩選
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type
執(zhí)行結(jié)果:
product_type | count
-------------+------
衣服 | 2
辦公用品 | 2
廚房用具 | 4
通過對比可以發(fā)現(xiàn)我們并沒有將條數(shù)為2的數(shù)據(jù)篩選出來
2. HAVING的使用條件
HAVING和GROUP BY 類似,可以使用在HAVING里面的表達(dá)式:
- 常數(shù)
- 聚合函數(shù)
- GROUP BY 指定的列名(即聚合鍵)
2.1 錯誤的使用HAVING
示例:錯誤使用HAVING
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type
HAVING product_name = '圓珠筆';
執(zhí)行結(jié)果:
ERROR: 列"product,product_name"必須包含在GROUP BY子句當(dāng)中,或者必須在聚合函數(shù)中使用
行 4: HAVING product_name = '圓珠筆';
錯誤原因在于product_name這個字段既不是聚合函數(shù),也沒有包含在GROUP BY 指定列里面。所以報錯。
如果想正確使用需要這么寫:
示例:正確使用HAVING
SELECT
product_type,
COUNT(*)
FROM
Product
GROUP BY product_type
HAVING product_type = '衣服'
執(zhí)行結(jié)果:
product_type | count
-------------+------
衣服 | 2
2.2 相對于 HAVING 更適合 WHERE 的語句
有些條件既可以寫在 HAVING 子句當(dāng)中,又可以寫在 WHERE 子句當(dāng)中。這些條件就是聚合鍵所對應(yīng)的條件。原表中作為聚合鍵的列也可以在 HAVING 子句中使用。
**示例:既可以使用 HAVING 又可以使用 WHERE **
SELECT
product_type,
COUNT(*)
FROM
Product
WHERE product_type = '衣服'
GROUP BY product_type
-- HAVING product_type = '衣服'
執(zhí)行結(jié)果:
product_type | count
-------------+------
衣服 | 2
2.3 什么時候用 WHERE 什么時候使用 HAVING 呢?
- WHERE 子句 = 指定行所對應(yīng)的條件
- HAVING 子句 = 指定組所對應(yīng)的條件
- WHERE 處理速度比 HAVING 處理速度高
- 聚合鍵所對應(yīng)的條件不應(yīng)該書寫在 HAVING 子句當(dāng)中,而應(yīng)該書寫在 WHERE 子句當(dāng)中。