SQL 实战-巧用 CASE WHEN 实现条件分组与统计

在 SQL 查询中,CASE WHEN 是一个非常强大的条件表达式,能够灵活地实现复杂的分组、统计、分类汇总等功能。尤其在进行报表开发或数据分析时,CASE WHEN 可以帮助我们轻松实现条件分组统计,而不必依赖多次查询或编写复杂的存储过程。

本文将通过实际案例,展示如何巧妙使用 CASE WHEN 实现条件分组与统计。


一、CASE WHEN 基本语法

sql 复制代码
CASE  
    WHEN 条件1 THEN 结果1  
    WHEN 条件2 THEN 结果2  
    ELSE 默认结果  
END  

特点

  • 可以嵌套在 SELECTWHEREGROUP BYHAVING 等语句中。
  • CASE 语句可以根据不同的条件返回不同的结果,从而实现复杂的逻辑分支。

二、条件分组统计实战案例

1. 销售额按区域分类统计

需求:统计每个区域销售额,并按以下条件分类汇总:

  • 销售额大于 5000 为"高销量"。
  • 销售额在 2000-5000 之间为"中销量"。
  • 销售额小于 2000 为"低销量"。

表结构 sales

sales_id region employee amount
1 East Alice 6000
2 East Bob 4500
3 West Carol 1500
4 West David 7000
5 East Eve 1200

SQL 实现
sql 复制代码
SELECT  
    region,  
    COUNT(CASE WHEN amount > 5000 THEN 1 END) AS 高销量,  
    COUNT(CASE WHEN amount BETWEEN 2000 AND 5000 THEN 1 END) AS 中销量,  
    COUNT(CASE WHEN amount < 2000 THEN 1 END) AS 低销量  
FROM sales  
GROUP BY region;  

查询结果

region 高销量 中销量 低销量
East 1 1 1
West 1 0 1

解释

  • 条件分组统计CASE WHEN 通过判断条件返回 1NULL,再通过 COUNT 统计非空记录,实现条件统计分组。
  • 高效执行 :相比多次查询,CASE WHEN 可以在一次扫描中完成多个条件分组统计,提高执行效率。

三、实现多重分类统计

2. 按销售额区间统计销售记录数

需求:统计所有销售记录,并按销售额区间进行分类统计:

  • 0-1000 为"极低"。
  • 1001-3000 为"低"。
  • 3001-6000 为"中"。
  • 6001 以上为"高"。

SQL 实现
sql 复制代码
SELECT  
    COUNT(*) AS 总记录数,  
    COUNT(CASE WHEN amount BETWEEN 0 AND 1000 THEN 1 END) AS 极低,  
    COUNT(CASE WHEN amount BETWEEN 1001 AND 3000 THEN 1 END) AS 低,  
    COUNT(CASE WHEN amount BETWEEN 3001 AND 6000 THEN 1 END) AS 中,  
    COUNT(CASE WHEN amount > 6000 THEN 1 END) AS 高  
FROM sales;  

查询结果

总记录数 极低
5 1 1 2 1

解释

  • COUNT(*) 统计所有记录数。
  • CASE WHEN 将不同的销售额区间分类统计并汇总在同一结果集中。

四、统计百分比与占比

3. 统计各区域销售额占比

需求:统计每个区域的销售额总和及其占总销售额的百分比。


SQL 实现
sql 复制代码
SELECT  
    region,  
    SUM(amount) AS 区域销售额,  
    ROUND(SUM(amount) * 100 / SUM(SUM(amount)) OVER (), 2) AS 占比  
FROM sales  
GROUP BY region;  

查询结果

region 区域销售额 占比
East 11700 58.50
West 8500 41.50

解释

  • SUM(SUM(amount)) OVER () 计算全表销售总额。
  • 每个区域的销售额除以总销售额计算出占比。
  • 使用 ROUND 保留两位小数。

五、按条件汇总多列统计

4. 多列条件分组统计

需求:统计每个区域销售额大于 5000 的记录数,并计算销售总额和平均值。


SQL 实现
sql 复制代码
SELECT  
    region,  
    COUNT(*) AS 记录总数,  
    COUNT(CASE WHEN amount > 5000 THEN 1 END) AS 高销量,  
    SUM(amount) AS 总销售额,  
    AVG(amount) AS 平均销售额  
FROM sales  
GROUP BY region;  

查询结果

region 记录总数 高销量 总销售额 平均销售额
East 3 1 11700 3900
West 2 1 8500 4250

六、应用场景与优化建议

1. 应用场景
  • 动态报表生成:在生成销售报表、业绩分析时,可以动态按条件分类汇总。
  • 数据清洗与分组:在数据清洗和预处理过程中,快速按条件对数据进行分组统计。
  • 复杂条件筛选:在多条件组合筛选时,可以避免大量子查询,提升查询效率。

2. 优化建议
  1. 利用索引 :为参与 CASE WHEN 条件判断的字段建立索引,减少全表扫描。
  2. 避免嵌套:尽量避免嵌套子查询,将逻辑在一次查询中完成。
  3. 分组粒度控制:合理选择分区字段,避免分区粒度过大,导致结果集过多或过少。

七、总结

  • CASE WHEN 是 SQL 查询中不可或缺的利器,能够灵活地实现多条件分组、分类统计和数据清洗。
  • 通过嵌套在 COUNT()SUM() 等聚合函数中,CASE WHEN 可以实现条件汇总与分组,极大地提高 SQL 查询的灵活性和效率。
  • 在实际开发中,合理使用 CASE WHEN 可以减少冗余查询,提升代码可读性和维护性,帮助快速完成复杂的业务需求。
相关推荐
Acrelgq2331 分钟前
工厂能耗系统智能化解决方案 —— 安科瑞企业能源管控平台
大数据·人工智能·物联网
D愿你归来仍是少年3 小时前
使用 PySpark 批量清理 Hive 表历史分区
大数据·数据仓库·hive·spark
End9284 小时前
Hadoop的三大结构及其作用?
大数据·hadoop·分布式
Paraverse_徐志斌4 小时前
MySQL 线上大表 DDL 如何避免锁表(pt-online-schema-change)
数据库·mysql·ddl·mysql锁·锁表·pt-osc
哈哈幸运5 小时前
MySQL运维三部曲初级篇:从零开始打造稳定高效的数据库环境
linux·运维·数据库·mysql·性能优化
愚公搬代码5 小时前
【愚公系列】《Python网络爬虫从入门到精通》055-Scrapy_Redis分布式爬虫(安装Redis数据库)
数据库·爬虫·python
pwzs5 小时前
深入浅出 MVCC:MySQL 并发背后的多版本世界
数据库·后端·mysql
大熊猫今天吃什么5 小时前
【一天一坑】空数组,使用 allMatch 默认返回true
前端·数据库
chat2tomorrow6 小时前
数据仓库 vs 数据湖:架构、应用场景与技术差异全解析
大数据·数据仓库·低代码·架构·数据湖·sql2api
双叶8366 小时前
(51单片机)LCD显示数据存储(DS1302时钟模块教学)(LCD1602教程)(独立按键教程)(延时函数教程)(I2C总线认识)(AT24C02认识)
c语言·数据库·单片机·嵌入式硬件·mongodb·51单片机·nosql