为聚合结果指定条件
如果想要从 GROUP BY 分组中进行筛选的话,不是用 WHERE 而是使用 HAVING 来进行聚合函数的筛选。
比如之前问过的问题,如何从商品分类汇总中找到条数为2的商品种类呢?
image.png
1. HAVING子句
HAVING 子句写法:
SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
GROUP BY <列名1>, <列名2>, <列名3>, ……
HAVING <分组结果对应的条件>
HAVING 子句必须写在GROUP BY 子句之后,其在DBMS 内部的执行顺序也排在GROUP BY 子句之后。
使用HAVING 子句时SELECT 语句的顺序
SELECT → FROM → WHERE → GROUP BY → HAVING
1.1使用HAVING进行分组筛选
接下来就让我们练习一下HAVING 子句吧。例如,针对按照商品种类进行分组后的结果,指定“包含的数据行数为2 行”这一条件的SELECT 语句。
示例:查询商品分类条数汇总并将条数为2的商品提取出来
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type
HAVING COUNT(*) = 2;
执行结果:
product_type | count
-------------+------
衣服 | 2
办公用品 | 2
1.2 对比不使用 HAVING 的情况下 SQL 语句执行的情况
示例:不使用HAVING进行条件筛选
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type
执行结果:
product_type | count
-------------+------
衣服 | 2
办公用品 | 2
厨房用具 | 4
通过对比可以发现我们并没有将条数为2的数据筛选出来
2. HAVING的使用条件
HAVING和GROUP BY 类似,可以使用在HAVING里面的表达式:
- 常数
- 聚合函数
- GROUP BY 指定的列名(即聚合键)
2.1 错误的使用HAVING
示例:错误使用HAVING
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type
HAVING product_name = '圆珠笔';
执行结果:
ERROR: 列"product,product_name"必须包含在GROUP BY子句当中,或者必须在聚合函数中使用
行 4: HAVING product_name = '圆珠笔';
错误原因在于product_name
这个字段既不是聚合函数,也没有包含在GROUP BY 指定列里面。所以报错。
如果想正确使用需要这么写:
示例:正确使用HAVING
SELECT
product_type,
COUNT(*)
FROM
Product
GROUP BY product_type
HAVING product_type = '衣服'
执行结果:
product_type | count
-------------+------
衣服 | 2
2.2 相对于 HAVING 更适合 WHERE 的语句
有些条件既可以写在 HAVING 子句当中,又可以写在 WHERE 子句当中。这些条件就是聚合键所对应的条件。原表中作为聚合键的列也可以在 HAVING 子句中使用。
**示例:既可以使用 HAVING 又可以使用 WHERE **
SELECT
product_type,
COUNT(*)
FROM
Product
WHERE product_type = '衣服'
GROUP BY product_type
-- HAVING product_type = '衣服'
执行结果:
product_type | count
-------------+------
衣服 | 2
2.3 什么时候用 WHERE 什么时候使用 HAVING 呢?
- WHERE 子句 = 指定行所对应的条件
- HAVING 子句 = 指定组所对应的条件
- WHERE 处理速度比 HAVING 处理速度高
- 聚合键所对应的条件不应该书写在 HAVING 子句当中,而应该书写在 WHERE 子句当中。
网友评论