SQL分组后条件求和难题,如何高效实现字段按需累加

文章导读
使用条件聚合函数CASE WHEN来实现分组后按需求和,这是最高效的方法,避免子查询和多表关联。核心代码如下:SELECT user_id, SUM(CASE WHEN type='income' THEN amount ELSE 0 END) AS total_income,SUM(CASE WHEN type='expense' THEN amount ELSE 0 END) AS total
📋 目录
  1. CSDN博客
  2. SegmentFault
  3. 知乎回答
  4. 博客园
  5. 阿里云开发者社区
  6. MySQL官方文档示例
A A

使用条件聚合函数CASE WHEN来实现分组后按需求和,这是最高效的方法,避免子查询和多表关联。核心代码如下:
SELECT user_id,
SUM(CASE WHEN type='income' THEN amount ELSE 0 END) AS total_income,
SUM(CASE WHEN type='expense' THEN amount ELSE 0 END) AS total_expense,
SUM(amount) AS total_amount
FROM transactions
GROUP BY user_id;

CSDN博客

在GROUP BY分组后,我们经常遇到需要根据不同条件对某些字段分别求和的情况。传统方法是用HAVING子句或者子查询,但性能很差。高效方式是用SUM + CASE WHEN条件判断。
比如订单表,按用户分组,分别统计正常订单金额和退款订单金额:
SELECT
user_id,
SUM(CASE WHEN status='normal' THEN order_amount ELSE 0 END) normal_amount,
SUM(CASE WHEN status='refund' THEN order_amount ELSE 0 END) refund_amount
FROM orders
GROUP BY user_id;

SegmentFault

SQL分组后条件求和最简单高效的方法就是条件聚合:
select
dept_id,
sum(case when gender='男' then 1 else 0 end) male_count,
sum(case when gender='女' then 1 else 0 end) female_count
from employee
group by dept_id;

SQL分组后条件求和难题,如何高效实现字段按需累加

知乎回答

遇到分组后需要多个条件求和的场景,直接用CASE WHEN嵌套在聚合函数里就行,数据库优化器会很好处理。
select city,
count(*),
sum(case when age>18 then 1 else 0 end) adults,
sum(case when age<18 then 1 else 0 end) children
from users group by city;

博客园

条件求和经典用法:
SELECT
类别,
SUM(CASE WHEN 日期 = '2023-01' THEN 销售额 ELSE 0 END) AS '1月销售额',
SUM(CASE WHEN 日期 = '2023-02' THEN 销售额 ELSE 0 END) AS '2月销售额'
FROM 销售表
GROUP BY 类别

SQL分组后条件求和难题,如何高效实现字段按需累加

阿里云开发者社区

高效实现字段按需累加的关键是避免重复扫描数据,使用单一聚合查询:
select product_id,
sum(case when store='A' then qty else 0 end) as qty_A,
sum(case when store='B' then qty else 0 end) as qty_B
from inventory group by product_id;

SQL分组后条件求和难题,如何高效实现字段按需累加

MySQL官方文档示例

使用条件聚合可以动态计算多个汇总值:
SELECT orderpriority, fact.orderdate, count(*) AS order_count,
SUM(CASE WHEN action = 'closed' THEN 1 ELSE 0 END) AS closed_cnt
FROM orders o JOIN facts f ON o.orderkey = f.orderkey
GROUP BY orderpriority, fact.orderdate;

FAQ
Q: 为什么不用子查询来实现条件求和?
A: 子查询会导致数据多次扫描,性能差;条件聚合只需扫描一次。
Q: MySQL和PostgreSQL都支持这种写法吗?
A: 是的,所有主流数据库都支持CASE WHEN在聚合函数中使用。
Q: 如果条件很复杂怎么办?
A: 可以用多个嵌套CASE,或者预先用CTE过滤数据。
Q: 能不能用IF函数代替CASE WHEN?
A: 可以,在MySQL中SUM(IF(condition, value, 0))效果相同。