SQL 中 WHERE 与 HAVING 子句的使用
在编写 SQL 查询时,数据过滤是常见需求。WHERE 和 HAVING 子句虽然都用于筛选数据,但实际用法大不相同。本文通过具体示例对比两者的核心区别,并结合实际场景演示联合使用技巧,助力快速掌握这两个关键工具的正确用法。
一、数据表结构
假设存在 sales
表,其结构如下:
sale_id | product_id | sale_date | sale_amount |
---|---|---|---|
1 | 101 | 2024-01-01 | 100 |
2 | 101 | 2024-01-02 | 200 |
3 | 102 | 2024-01-03 | 150 |
4 | 103 | 2024-01-04 | 300 |
5 | 103 | 2024-01-05 | 250 |
二、WHERE 子句
(一)功能
用于过滤行数据,直接作用于表中的单行数据,在分组操作之前应用。
(二)特点
不能使用聚合函数。
假设尝试在 WHERE
中使用聚合函数:
SELECT product_id, SUM(sale_amount) AS total_sales
FROM sales
WHERE SUM(sale_amount) > 150; -- ❌ 错误:WHERE 无法使用聚合函数
错误原因:
执行 WHERE
时,尚未对 sale_amount
进行求和计算,因此 SUM(sale_amount)
不存在。
(三)准确示例
假设要找出 sale_amount
大于 150 的销售记录。
SELECT *
FROM sales
WHERE sale_amount > 150;
结果:
sale_id | product_id | sale_date | sale_amount |
---|---|---|---|
2 | 101 | 2024-01-02 | 200 |
4 | 103 | 2024-01-04 | 300 |
5 | 103 | 2024-01-05 | 250 |
三、HAVING 子句
(一)功能
用于过滤分组后的结果集,作用于分组后的数据,在分组操作之后应用。
(二)特点
可以使用聚合函数(如 SUM()
、AVG()
、COUNT()
等)来定义过滤条件。
(三)具体示例
假设要找出销售总额超过 400 的产品。
SELECT product_id, SUM(sale_amount) AS total_sales
FROM sales
GROUP BY product_id
HAVING SUM(sale_amount) > 400;
结果:
product_id | total_sales |
---|---|
103 | 550 |
四、WHERE 和 HAVING 结合使用
(一)使用场景
当需要先对行数据进行过滤,再对分组结果进行过滤时,可结合使用 WHERE
和 HAVING
子句。
(二)示例
假设要找出销售总额超过 400 的产品,并且只考虑在 2024 年 1 月 4 日及之后的销售记录。
SELECT product_id, SUM(sale_amount) AS total_sales
FROM sales
WHERE sale_date >= '2024-01-04'
GROUP BY product_id
HAVING SUM(sale_amount) > 400;
结果:
product_id | total_sales |
---|---|
103 | 550 |
(三)执行顺序
WHERE
子句先对sales
表中的行进行过滤,只选择sale_date
大于或等于 2024 年 1 月 4 日的记录。GROUP BY
对过滤后的数据按product_id
进行分组。HAVING
子句对分组后的结果进行过滤,只选择销售总额超过 400 的产品。