当前位置: 首页 > 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.lryc.cn/news/605978.html

相关文章:

  • Spring AI 系列之二十八 - Spring AI Alibaba-基于Nacos的prompt模版
  • HCIP面试第一章内容总结
  • 【LeetCode 热题 100】4. 寻找两个正序数组的中位数——(解法一)线性扫描
  • 【ARM】PK51关于内存模式的解析与选择
  • 全基因组关联分析(GWAS)中模型参数选择:MLM、GLM与FarmCPU的深度解析
  • 【08】大恒相机SDK C#发开 —— 多相机采集
  • 家政小程序系统开发:满足多元家政需求
  • 智慧油站漏检率↓78%:陌讯多模态融合算法的风险防控实践
  • linux线程封装和互斥
  • WinForm之CheckBox 控件
  • FPGA实现AD9361采集转SRIO与DSP交互,FPGA+DSP多核异构信号处理架构,提供2套工程源码和技术支持
  • Golang 调试技巧:在 Goland 中查看 Beego 控制器接收的前端字段参数
  • 在超算平台异构加速卡AI * 1卡的Ubuntu20.04环境下安装docker服务(未成功)
  • 【Golang】用官方rate包构造简单IP限流器
  • 【14】大恒相机SDK C#开发 ——Bitmap.UnlockBits()什么意思?有什么用?bmpData.Scan0;什么意思?有什么用?
  • go goroutine chan 用法
  • 网络编程(一)TCP编程和UDP编程
  • 前端工程化包管理器:从npm基础到nvm多版本管理实战
  • Vue多请求并行处理实战指南
  • Acrel-1000系列分布式光伏监控系统在湖北荆门一马光彩大市场屋顶光伏发电项目中应用
  • 【人工智能-15】OpenCV直方图均衡化,模板匹配,霍夫变换,图像亮度变换,形态学变换
  • webpack-babel
  • ESXI虚拟交换机 + H3C S5120交换机 + GR5200路由器组网笔记
  • 如何将照片从 realme 手机传输到电脑?
  • 使用橙武低代码平台构建摄影店管理系统的完整指南
  • 【爬虫实战】使用Python和JS逆向基于webpack的游戏平台
  • Rust × WebAssembly 项目脚手架详解
  • Kubernetes 应用部署实战:为什么需要 Kubernetes?
  • 本土发货模式兴起,如何选择合适的海外仓系统?
  • 单张卡牌类