0

0

sql怎样使用having结合聚合函数筛选数据 sql聚合筛选与having用法的技巧

爱谁谁

爱谁谁

发布时间:2025-08-19 08:28:01

|

660人浏览过

|

来源于php中文网

原创

HAVING用于筛选分组后的聚合结果,WHERE用于过滤分组前的原始行数据;执行顺序上WHERE先于GROUP BY,HAVING在GROUP BY之后,二者可结合使用以提升查询效率。

sql怎样使用having结合聚合函数筛选数据 sql聚合筛选与having用法的技巧

HAVING
子句在SQL中,是专门用来筛选经过
GROUP BY
分组后的数据。它与
WHERE
子句不同,
WHERE
在数据分组之前对单行记录进行筛选,而
HAVING
则是在聚合函数(如
COUNT()
,
SUM()
,
AVG()
,
MAX()
,
MIN()
)计算出结果之后,再对这些聚合结果进行条件过滤。简单来说,如果你想基于某个总和、平均值或数量来筛选组,那就用
HAVING

解决方案

使用

HAVING
结合聚合函数筛选数据,其核心在于理解SQL查询的执行顺序。它总是在
GROUP BY
之后执行。基本语法结构是这样的:

SELECT
    column1,
    aggregate_function(column2)
FROM
    table_name
GROUP BY
    column1
HAVING
    aggregate_function(column2) [comparison_operator] value;

举个例子,假设我们有一个

orders
表,里面有
customer_id
amount
字段。我们想找出那些总订单金额超过1000的客户。

SELECT
    customer_id,
    SUM(amount) AS total_spent
FROM
    orders
GROUP BY
    customer_id
HAVING
    SUM(amount) > 1000;

这里,

SUM(amount)
是一个聚合函数,它计算了每个客户的总金额。
HAVING SUM(amount) > 1000
则是在这些总金额计算出来之后,筛选出那些总金额大于1000的客户。如果没有
HAVING
,我们是无法直接在
WHERE
子句中使用
SUM(amount)
的,因为
WHERE
是在行级别操作的。

HAVING与WHERE子句有何本质区别?何时选用它们?

这真的是SQL初学者,甚至是一些有经验的开发者都会偶尔混淆的点。我个人觉得,理解它们的执行时机是关键。

WHERE
子句,它就像是数据进入厨房前的第一道关卡,负责对每一份食材(每一行数据)进行检查,不符合条件的直接剔除,连锅都不让进。它作用于原始的、未聚合的行数据。所以,你不能在
WHERE
里直接用
COUNT()
SUM()
这类聚合函数,因为那时候数据还没“聚”起来。

HAVING
呢,它更像是菜肴出锅前的最后一道品控。当所有食材都经过烹饪(
GROUP BY
分组和聚合函数计算)变成了最终的菜品(聚合结果)后,
HAVING
才开始工作,检查这些“菜品”是否符合标准。比如,你做了一桌菜,
HAVING
会说:“这盘菜如果总重量小于500克,就不能上桌!”它看的是整体,是聚合后的结果。

什么时候用哪个?

  • WHERE
    当你需要基于原始行数据进行筛选时。比如,只统计“活跃”用户的订单,或者只考虑“2023年”的销售数据。这些条件都不依赖于聚合结果。

    -- 找出2023年单笔订单金额超过100的所有订单
    SELECT order_id, customer_id, amount
    FROM orders
    WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31'
    AND amount > 100;
  • HAVING
    当你的筛选条件依赖于聚合函数的结果时。比如,找出平均销售额超过某个数值的地区,或者至少有5个订单的客户。

    -- 找出平均订单金额超过200的客户
    SELECT customer_id, AVG(amount) AS avg_order_amount
    FROM orders
    GROUP BY customer_id
    HAVING AVG(amount) > 200;

有时候,两者甚至会一起出现。比如,我们想找出2023年那些总订单金额超过1000的客户。这时,先用

WHERE
筛选出2023年的订单,再用
GROUP BY
HAVING
来聚合和筛选。

SELECT
    customer_id,
    SUM(amount) AS total_spent
FROM
    orders
WHERE
    order_date BETWEEN '2023-01-01' AND '2023-12-31' -- 先筛选2023年的订单
GROUP BY
    customer_id
HAVING
    SUM(amount) > 1000; -- 再筛选总金额大于1000的客户

这种组合使用非常常见,也是写出高效且精确SQL的关键。

结合多个聚合函数或条件在HAVING中进行筛选的实际场景

HAVING
子句的强大之处在于,它不仅限于一个简单的聚合条件。你可以像在
WHERE
子句中那样,使用
AND
OR
NOT
等逻辑运算符来组合多个聚合条件,甚至结合多个不同的聚合函数进行筛选。这在处理复杂的业务逻辑时显得尤为有用。

想象一个场景:我们想找出那些平均订单金额超过500,并且总订单数至少有3个的客户。

SELECT
    customer_id,
    AVG(amount) AS avg_order_amount,
    COUNT(order_id) AS total_orders
FROM
    orders
GROUP BY
    customer_id
HAVING
    AVG(amount) > 500 AND COUNT(order_id) >= 3;

在这个例子中,我们同时使用了

AVG()
COUNT()
这两个聚合函数,并在
HAVING
子句中用
AND
将它们的条件连接起来。只有同时满足这两个条件的客户才会被返回。

码上飞
码上飞

码上飞(CodeFlying) 是一款AI自动化开发平台,通过自然语言描述即可自动生成完整应用程序。

下载

再来一个稍微复杂点的:找出那些总销售额超过10000,或者虽然总销售额没到10000但至少有100笔交易的商品。

SELECT
    product_id,
    SUM(sale_amount) AS total_sales,
    COUNT(transaction_id) AS total_transactions
FROM
    sales_records
GROUP BY
    product_id
HAVING
    SUM(sale_amount) > 10000 OR COUNT(transaction_id) >= 100;

这种灵活性让

HAVING
成为处理报表和数据分析中“基于汇总数据进行筛选”任务的利器。你可能会发现,很多时候业务部门提的需求,最终落实到SQL上,都需要
HAVING
来完成这种多维度、基于聚合结果的筛选。

在SQL查询优化中,HAVING的使用有哪些值得注意的地方?

谈到优化,

HAVING
的使用确实有一些值得我们思考的地方。我经常会看到一些查询,明明可以在
WHERE
子句中完成的筛选,却被放到了
HAVING
里。虽然结果可能一样,但性能上却可能大相径庭。

核心原则是:能用

WHERE
的,就不要用
HAVING

为什么这么说?因为

WHERE
子句在数据分组和聚合之前就对数据进行了过滤。这意味着它减少了需要处理的行数,从而减轻了
GROUP BY
和聚合函数的工作量。如果你的原始数据集非常庞大,先用
WHERE
过滤掉大量不相关的行,那么后续的聚合操作就会快很多。

举个例子:我们只想分析2023年的数据,并且找出总金额超过1000的客户。

低效的做法(尽量避免,如果条件可以下推到WHERE):

SELECT
    customer_id,
    SUM(amount) AS total_spent
FROM
    orders
GROUP BY
    customer_id
HAVING
    SUM(amount) > 1000
    AND MAX(order_date) >= '2023-01-01' -- 这里尝试用HAVING过滤年份,但效率不如WHERE
    AND MIN(order_date) <= '2023-12-31';

这里,

MAX(order_date)
MIN(order_date)
是聚合函数,所以它们必须在
HAVING
里。但如果目的只是筛选2023年的订单,那么在
WHERE
里直接过滤
order_date
列会更高效。

高效的做法:

SELECT
    customer_id,
    SUM(amount) AS total_spent
FROM
    orders
WHERE
    order_date BETWEEN '2023-01-01' AND '2023-12-31' -- 先在WHERE过滤年份
GROUP BY
    customer_id
HAVING
    SUM(amount) > 1000; -- 再在HAVING过滤聚合结果

在这个高效的例子中,数据库引擎首先会根据

WHERE
子句过滤掉所有非2023年的订单,这样
GROUP BY
SUM()
只需要处理2023年的数据,大大减少了计算量。

当然,有些时候你别无选择,条件本身就依赖于聚合结果,那就必须使用

HAVING
。这时候,我们能做的就是确保
GROUP BY
的列上建有合适的索引,这有助于加速分组过程。

总的来说,

HAVING
是SQL中一个非常强大且不可或缺的工具,但理解其在查询生命周期中的位置,并结合
WHERE
子句进行合理的划分,是写出高效、可维护SQL查询的关键一步。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

727

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

328

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

350

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1243

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

360

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

821

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

581

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

423

2024.04.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQL 教程
SQL 教程

共61课时 | 3.6万人学习

微信小程序开发之API篇
微信小程序开发之API篇

共15课时 | 1.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号