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

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.xdnf.cn/news/16673.html

相关文章:

  • Kotlin -> 普通Lambda vs 挂起Lambda
  • Side band ECC、Inline ECC、On-die ECC、Link ECC
  • Jinja2 详细讲解
  • 基于32nm CMOS工艺的传输门D触发器设计及HSPICE仿真分析
  • 三坐标测量仪攻克深孔检测!破解新能源汽车阀体阀孔测量难题
  • 电子电气架构 --- 车载48V系统开辟全新道路
  • React组件化的封装
  • 【Kiro Code】Chat 聊天功能
  • Amazon Aurora MySQL 8.0 完整指南
  • 网络爬虫(python)入门
  • 安卓基础布局核心知识点整理
  • 嵌入式 C 语言入门:循环结构学习笔记 —— 从语法到实用技巧
  • BH1750模块
  • TransportClient详细说一说
  • ClickHouse vs PostgreSQL:数据分析领域的王者之争,谁更胜一筹?
  • Cesium 快速入门(三)Viewer:三维场景的“外壳”
  • 停更通知!
  • 数据结构-Set集合(一)Set集合介绍、优缺点
  • 【HarmonyOS】鸿蒙应用HTTPDNS 服务集成详解
  • 《使用Qt Quick从零构建AI螺丝瑕疵检测系统》——8. AI赋能(下):在Qt中部署YOLOv8模型
  • 关系型数据库架构最优选择:基于落霞归雁思维框架的分析
  • ECMAScript2020(ES11)新特性
  • Apache HTTP Server 2.4.50 路径穿越漏洞(CVE-2021-42013)
  • 【LangChain4j 详解】Java生态大语言模型框架设计哲学与架构原理
  • Python多线程利器:重入锁(RLock)详解——原理、实战与避坑指南
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-50,(知识点:TCP/IP 模型)
  • electron开发桌面应用入门
  • Web UI自动化测试之PO篇
  • 【刷题】东方博宜oj 1307 - 数的计数
  • 域名https证书