HAVING和WHERE子句 有什么区别?

简介: 【8月更文挑战第2天】

在 SQL 中,HAVINGWHERE 子句是用于筛选数据的重要工具。尽管它们都用于过滤数据,但它们在使用场景和应用时机上存在显著区别。

一、基本概念

1. WHERE 子句

WHERE 子句用于从数据库表中筛选记录,它在 SQL 查询中指定条件,以过滤掉不满足条件的记录。WHERE 子句只能用于原始数据的过滤,即在聚合函数计算之前进行数据筛选。

SELECT column1, column2, ...
FROM table_name
WHERE condition;

2. HAVING 子句

HAVING 子句通常与 GROUP BY 子句一起使用,用于对分组后的数据进行过滤。它在聚合函数计算之后应用,以便根据聚合结果筛选分组。

SELECT column1, column2, ..., aggregate_function(column)
FROM table_name
GROUP BY column1, column2, ...
HAVING condition;

二、使用场景和差异

1. 使用时机

  • WHERE 子句:在数据分组之前过滤数据。它用于在聚合函数计算之前筛选原始数据。
  • HAVING 子句:在数据分组之后过滤数据。它用于在聚合函数计算之后筛选分组结果。

2. 适用范围

  • WHERE 子句:可以用于任何非聚合的条件表达式。
  • HAVING 子句:可以用于任何条件表达式,包括聚合函数的结果。

3. 示例分析

以下示例通过一个名为 Sales 的表来说明 WHEREHAVING 子句的使用。假设 Sales 表的结构如下:

CREATE TABLE Sales (
    SaleID INT,
    Product VARCHAR(50),
    Quantity INT,
    Price DECIMAL(10, 2),
    SaleDate DATE
);

数据如下:

SaleID Product Quantity Price SaleDate
1 A 10 20.00 2023-01-01
2 B 5 15.00 2023-01-02
3 A 8 22.00 2023-01-03
4 C 12 10.00 2023-01-04
5 B 7 15.00 2023-01-05
示例 1:使用 WHERE 子句

我们想要查找销售日期在 2023 年 1 月 2 日之后的所有销售记录。

SELECT *
FROM Sales
WHERE SaleDate > '2023-01-02';

结果:

SaleID Product Quantity Price SaleDate
3 A 8 22.00 2023-01-03
4 C 12 10.00 2023-01-04
5 B 7 15.00 2023-01-05
示例 2:使用 HAVING 子句

我们想要查找每种产品的总销售量大于 15 的产品。

SELECT Product, SUM(Quantity) AS TotalQuantity
FROM Sales
GROUP BY Product
HAVING SUM(Quantity) > 15;

结果:

Product TotalQuantity
A 18
B 12

三、 WHERE 和 HAVING 的组合使用

在一些复杂查询中,我们可能需要同时使用 WHEREHAVING 子句。以下示例展示了如何结合使用这两个子句:

我们想要查找销售日期在 2023 年 1 月 2 日之后的所有销售记录中,每种产品的总销售量大于 10 的产品。

SELECT Product, SUM(Quantity) AS TotalQuantity
FROM Sales
WHERE SaleDate > '2023-01-02'
GROUP BY Product
HAVING SUM(Quantity) > 10;

结果:

Product TotalQuantity
A 8
C 12

在这个示例中,WHERE 子句首先过滤掉销售日期在 2023 年 1 月 2 日之前的记录,然后 HAVING 子句进一步筛选每种产品的总销售量大于 10 的分组。

四、 WHERE 和 HAVING 子句的执行顺序

理解 WHEREHAVING 子句的执行顺序有助于更好地应用它们:

  1. FROM:首先从指定的表中检索数据。
  2. WHERE:然后应用 WHERE 子句过滤记录。
  3. GROUP BY:接着对过滤后的记录进行分组。
  4. HAVING:之后应用 HAVING 子句对分组结果进行过滤。
  5. SELECT:最后返回满足条件的记录。

五、详细示例和应用

以下示例进一步说明 WHEREHAVING 子句在实际应用中的差异和结合使用。

示例 1:统计每种产品的总销售量和总收入,并过滤掉总销售量小于 10 的产品。

SELECT Product, SUM(Quantity) AS TotalQuantity, SUM(Quantity * Price) AS TotalRevenue
FROM Sales
GROUP BY Product
HAVING SUM(Quantity) >= 10;

结果:

Product TotalQuantity TotalRevenue
A 18 420.00
B 12 180.00

示例 2:统计销售日期在 2023 年 1 月 2 日之后的每种产品的总销售量和总收入,并过滤掉总销售量小于 10 的产品。

SELECT Product, SUM(Quantity) AS TotalQuantity, SUM(Quantity * Price) AS TotalRevenue
FROM Sales
WHERE SaleDate > '2023-01-02'
GROUP BY Product
HAVING SUM(Quantity) >= 10;

结果:

Product TotalQuantity TotalRevenue
C 12 120.00

示例 3:在包含子查询的复杂查询中使用 WHERE 和 HAVING

我们想要查找每种产品的平均销售价格,并筛选出平均价格高于 15 的产品,同时只考虑总销售量大于 10 的产品。

SELECT Product, AVG(Price) AS AvgPrice
FROM (
    SELECT Product, SUM(Quantity) AS TotalQuantity, AVG(Price) AS Price
    FROM Sales
    GROUP BY Product
    HAVING SUM(Quantity) > 10
) AS FilteredSales
GROUP BY Product
HAVING AVG(Price) > 15;

结果:

Product AvgPrice
A 21.00

在这个示例中,内部查询首先使用 HAVING 子句过滤出总销售量大于 10 的产品,然后外部查询计算这些产品的平均销售价格,并使用 HAVING 子句进一步筛选出平均价格高于 15 的产品。

六、总结

WHEREHAVING 子句在 SQL 查询中的使用有着显著的区别。WHERE 子句用于在数据分组和聚合计算之前进行数据筛选,而 HAVING 子句用于在分组和聚合计算之后进行数据筛选。理解它们的区别和适用场景,可以帮助我们在实际工作中更有效地进行数据查询和分析。

相关实践学习
【AI破次元壁合照】少年白马醉春风,函数计算一键部署AI绘画平台
本次实验基于阿里云函数计算产品能力开发AI绘画平台,可让您实现“破次元壁”与角色合照,为角色换背景效果,用AI绘图技术绘出属于自己的少年江湖。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
目录
相关文章
|
5月前
|
存储 BI API
一文读懂数据中台和数据仓库的区别
本文深入解析了“数据中台”与“数据仓库”的区别,从定义、功能、架构设计、数据处理、应用场景等多个维度进行对比,帮助企业更清晰地理解二者的核心差异与适用场景。数据仓库重在存储与分析历史数据,服务于高层决策;数据中台则强调数据的实时处理与服务化输出,直接赋能一线业务。文章还结合企业规模、业务需求与技术能力,给出了选型建议,助力企业在数字化转型中做出更科学的选择。
1172 11
|
存储 数据库管理 索引
索引的优点和缺点是什么
【10月更文挑战第15天】索引的优点和缺点是什么
|
API 开发者
GraphQL全面深度讲解
GraphQL是一种查询语言和运行引擎,允许开发者在一个请求中自定义并获取所有所需数据,提供准确且无冗余的数据返回,但可能需要开发者学习新的语言并投入更多时间来维护数据模型。
693 5
GraphQL全面深度讲解
|
9月前
|
机器学习/深度学习 人工智能 机器人
阿里通义开源推理模型新王者!QwQ-32B:性能直逼671B的DeepSeek-R1
QwQ-32B 是阿里巴巴开源的新型推理模型,基于强化学习训练,具备强大的数学推理和编程能力,性能媲美更大参数量的模型。
912 8
阿里通义开源推理模型新王者!QwQ-32B:性能直逼671B的DeepSeek-R1
|
SQL 关系型数据库 MySQL
【MySQL】where和having的区别
【MySQL】where和having的区别
零基础入门金融风控之贷款违约预测的Task1:赛题理解
零基础入门金融风控之贷款违约预测的Task1:赛题理解
236 4
|
网络协议 SDN 数据安全/隐私保护
|
Java 测试技术 数据库连接
SpringBoot单元测试 Mybatis:增删改查
SpringBoot单元测试 Mybatis:增删改查
1403 0
|
前端开发 JavaScript
js【详解】async await
js【详解】async await
190 0