当前位置: 首页 > news >正文

SQL 中 WHERE 与 HAVING 的用法详解:分组聚合场景下的混用指南

SQL中WHERE与HAVING的用法详解:分组聚合场景下的混用指南

1. WHERE与HAVING的基本区别

在SQL查询中,WHERE和HAVING都是用于过滤数据的子句,但它们的应用时机和作用对象有本质区别:

  • WHERE子句:在分组前对原始数据进行过滤,作用于单行记录
  • HAVING子句:在分组后对聚合结果进行过滤,作用于分组结果
-- WHERE示例:筛选单价大于100的产品
SELECT product_id, product_name 
FROM products 
WHERE price > 100;-- HAVING示例:筛选平均分大于80的班级
SELECT class_id, AVG(score) as avg_score
FROM students
GROUP BY class_id
HAVING AVG(score) > 80;

2. 分组聚合场景下的混用原则

在分组查询中,WHERE和HAVING可以协同工作,遵循以下处理流程:

  1. WHERE条件先执行,过滤掉不符合条件的原始记录
  2. 对过滤后的数据进行分组(GROUP BY)
  3. 计算各组的聚合值
  4. HAVING条件最后执行,过滤掉不符合条件的分组

3. 典型混用场景示例

-- 查询2023年销售额超过10万的销售员及其销售额
SELECT salesperson_id,SUM(amount) as total_sales
FROM sales
WHERE sale_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY salesperson_id
HAVING total_sales > 100000;

执行顺序:

  1. 先通过WHERE筛选2023年的销售记录
  2. 按销售员分组
  3. 计算每个销售员的总销售额
  4. 最后用HAVING筛选总销售额>10万的分组

4. 常见误区与注意事项

  1. WHERE中不能使用聚合函数

    -- 错误写法
    SELECT department, AVG(salary)
    FROM employees
    WHERE AVG(salary) > 5000  -- 错误!WHERE不能包含聚合函数
    GROUP BY department;-- 正确写法应使用HAVING
    SELECT department, AVG(salary)
    FROM employees
    GROUP BY department
    HAVING AVG(salary) > 5000;
    
  2. HAVING中可以使用非聚合列,但必须出现在GROUP BY中

    -- 合法写法
    SELECT department, AVG(salary)
    FROM employees
    GROUP BY department
    HAVING department LIKE 'A%';  -- department在GROUP BY中-- 不推荐写法(虽然语法可能允许)
    SELECT department, AVG(salary)
    FROM employees
    GROUP BY department
    HAVING employee_id = 100;  -- employee_id不在GROUP BY中,结果不可预测
    

5. 分不清莫不如不用HAVING?

HAVING可以理解为对分组结果的临时表做WHERE过滤。

HAVING本质上是GROUP BY操作的一部分,专门为分组后过滤设计的语法糖​​。

上面的例子也可以写成:

-- 查询2023年销售额超过10万的销售员及其销售额
SELECT t.salesperson_id, t.total_sales 
FROM (SELECT salesperson_id,SUM(amount) as total_salesFROM salesWHERE sale_date BETWEEN '2023-01-01' AND '2023-12-31'GROUP BY salesperson_id
) t 
WHERE t.total_sales > 100000;

两者的共同点​​:

  1. 都先过滤2023年的销售记录
  2. 都按销售员分组计算总销售额
  3. 都筛选出总销售额>10万的结果
  4. 返回的列和数据类型完全相同

6. 总结

WHERE和HAVING在分组聚合查询中的混用是SQL中强大的功能,掌握它们的区别和配合使用可以:

  1. 先通过WHERE高效过滤原始数据,减少处理量
  2. 再通过GROUP BY进行分组计算
  3. 最后用HAVING筛选有意义的分组结果
  4. HAVING等价于子查询+WHERE

合理运用这两个子句,可以编写出既高效又精确的聚合查询,满足复杂的数据分析需求。

http://www.dtcms.com/a/308433.html

相关文章:

  • 大数据平台数仓数湖hive之拉链表高效实现
  • 深度学习入门:用pytorch跑通GitHub的UNET-ZOO项目
  • 云服务器数据库
  • Camx-查看sensor mode 和效果参数
  • (LeetCode 每日一题) 2683. 相邻值的按位异或 (位运算)
  • 网络操作系统与应用服务器-1
  • SIwave 中 SIwizard 的 500 多个标准列表
  • 代码详细注释:演示多线程如何安全操作共享变量,使用互斥锁避免数据竞争。
  • Linux 文件系统基本管理
  • minidocx: 在C++11环境下运行的解决方案(二)
  • 网络攻击新态势企业级安全防御指南
  • Git分支管理:每个分支为什么这么命名?
  • Acrobat DC 应用安全配置:沙箱防护、数字签名
  • 了解微前端和SSO单点登录
  • Linux/Ubuntu 系统中打开火狐firefox、chromium浏览器失败
  • (三)从零搭建unity3d机器人仿真:使用WheelCollider实现turtlebot轮子差速运动
  • Linux系统编程-gcc(黑马笔记)
  • 译 | 用于具有外生特征的时间序列预测模型TimeXer
  • JavaScript 大数运算!
  • Abp+ShardingCore+EFCore.BulkExtensions使用案例
  • MCU中的DAC(数字模拟转换器)是什么?
  • 动态挑战-响应机制和密钥轮换
  • 算法练习:JZ32 从上往下打印二叉树
  • iOS高级开发工程师面试——其他
  • 磁盘坏道检测工具在美国服务器硬件维护中的使用规范
  • Linux 计划任务管理
  • 【在线五子棋对战】十一、整合封装服务器模块实现
  • linux git ssh配置过程
  • chrome.storage 和 localStorage
  • 自动化与配置管理工具 ——SaltStack