在 SQL 查询中,CASE WHEN
是一个非常强大的条件表达式,能够灵活地实现复杂的分组、统计、分类汇总等功能。尤其在进行报表开发或数据分析时,CASE WHEN
可以帮助我们轻松实现条件分组统计,而不必依赖多次查询或编写复杂的存储过程。
本文将通过实际案例,展示如何巧妙使用 CASE WHEN
实现条件分组与统计。
一、CASE WHEN 基本语法
sql">CASE WHEN 条件1 THEN 结果1 WHEN 条件2 THEN 结果2 ELSE 默认结果
END
特点:
- 可以嵌套在
SELECT
、WHERE
、GROUP BY
、HAVING
等语句中。 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
通过判断条件返回1
或NULL
,再通过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. 优化建议
- 利用索引:为参与
CASE WHEN
条件判断的字段建立索引,减少全表扫描。 - 避免嵌套:尽量避免嵌套子查询,将逻辑在一次查询中完成。
- 分组粒度控制:合理选择分区字段,避免分区粒度过大,导致结果集过多或过少。
七、总结
CASE WHEN
是 SQL 查询中不可或缺的利器,能够灵活地实现多条件分组、分类统计和数据清洗。- 通过嵌套在
COUNT()
、SUM()
等聚合函数中,CASE WHEN
可以实现条件汇总与分组,极大地提高 SQL 查询的灵活性和效率。 - 在实际开发中,合理使用
CASE WHEN
可以减少冗余查询,提升代码可读性和维护性,帮助快速完成复杂的业务需求。