3-3为聚合结果指定条件

SQL
Author

Rui

Published

November 12, 2022

3-3 为聚合结果指定条件

HAVING 子句

上一节末尾说到,聚合函数不能放入 WHERE 子句中,那么如何选出“聚合结果为 2 的组”呢?

SELECT <列名1>, ...
  FROM <表名>
 GROUP BY <列名1>, ...
HAVING <分组结果对应的条件>;
Note

书写顺序:

SELECT -> FROM -> WHERE -> GROUP BY -> HAVING

执行顺序:

FROM -> WHERE -> GROUP BY -> HAVING -> SELECT

按照商品种类分组,选出聚合结果为 2 的组:

SELECT product_type, COUNT(*)
  FROM Product
 GROUP BY product_type
HAVING COUNT(*) = 2;
2 records
product_type count
衣服 2
办公用品 2

按照商品种类分组,选出平均售价大于 2500 的组:

SELECT product_type, AVG(sale_price)
  FROM Product
 GROUP BY product_type
HAVING AVG(sale_price) >= 2500;
2 records
product_type avg
衣服 2500
厨房用具 2795

HAVING 子句的构成要素

HAVING 子句的要素为:常数聚合函数GROUP BY 子句中指定的列名(即聚合键)

如果 HAVING 中包含除聚合键以外的列名,则会报错。错误的方法:

SELECT product_type, COUNT(*)
  FROM Product
 GROUP BY product_type
HAVING product_name = '圆珠笔';

选择 HAVING 还是 WHERE ?

一些情况中,使用 HAVING 和 WHERE 能得到同样的结果,应该选择哪一种?比如:

SELECT product_type, COUNT(*)
  FROM Product
 GROUP BY product_type
HAVING product_type = '衣服';
1 records
product_type count
衣服 2
SELECT product_type, COUNT(*)
  FROM Product
 WHERE product_name = '圆珠笔'
 GROUP BY product_type;
1 records
product_type count
办公用品 1

解答:

  • 建议使用 WHERE

  • WHERE 比 HAVING 更快

  • HAVING 是用来指定分组聚合后“组”的条件的,WHERE 用于根据条件表达式筛选“行”。 使用时应该分清两者功能才能便于理解。

Tip

为什么 WHERE 比 HAVING 更快?

使用一些聚合函数的时候 DBMS 需要对数据进行排序,排序操作会加大机器的负担。 只有减少排序的行数,才能提高处理速度。 使用 WHERE 时,排序前就对数据进行筛选从而减少了数据的行数(执行顺序:WHERE 前 SELECT 后,COUNT 在 SELECT 中); 使用 HAVING 时,是先排序再对数据进行筛选的(执行顺序:HAVING 前 SELECT 后,COUNT 首先出现在 HAVING 中),相比于 WHERE 子句需要排序的数据量更大。