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 结合使用

(一)使用场景

当需要先对行数据进行过滤,再对分组结果进行过滤时,可结合使用 WHEREHAVING 子句。

(二)示例

假设要找出销售总额超过 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

(三)执行顺序

  1. WHERE 子句先对 sales 表中的行进行过滤,只选择 sale_date 大于或等于 2024 年 1 月 4 日的记录。
  2. GROUP BY 对过滤后的数据按 product_id 进行分组。
  3. HAVING 子句对分组后的结果进行过滤,只选择销售总额超过 400 的产品。
相关推荐
烬羽15 小时前
字符串算法入门:从反转字符串到回文判断,面试不再慌
算法·面试
先吃饱再说1 天前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰1 天前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术1 天前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
jiayou641 天前
KingbaseES 表级与列级加密完全指南
数据库·后端
AI小老六2 天前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术2 天前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize2 天前
初识DFS 与 BFS:递归、队列与图遍历
算法
罗西的思考2 天前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习