SQL 条件聚合 使用方法总结
核心:聚合函数 + 条件判断,分组内按条件统计不同维度数据
一、核心语法
sql
-- 基础格式
聚合函数(CASE WHEN 条件 THEN 字段 END) 别名
常用聚合:SUM/COUNT/AVG/MAX/MIN
二、常用场景&示例
1. 条件求和 SUM
按条件累加指定数据
sql
-- 统计男、女各自薪资总和
SELECT
SUM(CASE WHEN gender='男' THEN salary END) AS man_sal,
SUM(CASE WHEN gender='女' THEN salary END) AS woman_sal
FROM staff;
2. 条件计数 COUNT
统计符合条件的记录数
sql
-- 统计及格、不及格人数
SELECT
COUNT(CASE WHEN score>=60 THEN 1 END) AS pass_num,
COUNT(CASE WHEN score<60 THEN 1 END) AS fail_num
FROM exam;
3. 条件平均值 AVG
只计算满足条件数据的均值
sql
-- 计算正式员工平均工资
SELECT AVG(CASE WHEN status=1 THEN salary END) FROM staff;
4. 搭配 GROUP BY 分组条件聚合
分组后再细分条件统计
sql
-- 按部门分组,统计部门男女人数
SELECT
dept,
COUNT(CASE WHEN gender='男' THEN 1 END) AS man_cnt,
COUNT(CASE WHEN gender='女' THEN 1 END) AS woman_cnt
FROM staff
GROUP BY dept;
三、简写兼容写法
- MySQL专属
IF替代CASE,写法更简短
sql
SUM(IF(score>=60, score, 0))
COUNT(IF(gender='男',1,NULL))
- 空值特性:不满足条件返回NULL,聚合自动忽略
四、关键规则
- 满足条件取字段值,不满足默认返回NULL,聚合自动过滤空值
- 适合一行多指标统计,替代多次子查询,性能更高
- 可多层条件嵌套,实现区间分级统计
- 可和
GROUP BY、HAVING组合使用
五、区间统计实战
sql
-- 统计不同分数段人数
SELECT
COUNT(CASE WHEN score<60 THEN 1 END) AS low,
COUNT(CASE WHEN score BETWEEN 60 AND 80 THEN 1 END) AS mid,
COUNT(CASE WHEN score>80 THEN 1 END) AS high
FROM exam;
六、速记口诀
条件套进聚合里,CASE判断分数据
一行算出多维度,分组统计超便捷
Leetcode 经典例题
每月交易
表:Transactions
| Column Name | Type |
|---|---|
| id | int |
| country | varchar |
| state | enum |
| amount | int |
| trans_date | date |
id 是这个表的主键。
该表包含有关传入事务的信息。
state 列类型为 ["approved", "declined"] 之一。
编写一个 sql 查询来查找每个月和每个国家/地区的事务数及其总金额、已批准的事务数及其总金额。
以 任意顺序 返回结果表。
查询结果格式如下所示。
示例 1:
输入:
Transactions table:
| id | country | state | amount | trans_date |
|---|---|---|---|---|
| 121 | US | approved | 1000 | 2018-12-18 |
| 122 | US | declined | 2000 | 2018-12-19 |
| 123 | US | approved | 2000 | 2019-01-01 |
| 124 | DE | approved | 2000 | 2019-01-07 |
输出:
| month | country | trans_count | approved_count | trans_total_amount | approved_total_amount |
|---|---|---|---|---|---|
| 2018-12 | US | 2 | 1 | 3000 | 1000 |
| 2019-01 | US | 1 | 1 | 2000 | 2000 |
| 2019-01 | DE | 1 | 1 | 2000 | 2000 |
sql
SELECT
DATE_FORMAT(trans_date, '%Y-%m') AS month,
country,
COUNT(*) AS trans_count,
SUM(amount) AS trans_total_amount,
SUM(CASE WHEN state = 'approved' THEN 1 ELSE 0 END) AS approved_count,
SUM(CASE WHEN state = 'approved' THEN amount ELSE 0 END) AS approved_total_amount
FROM Transactions
GROUP BY
DATE_FORMAT(trans_date, '%Y-%m'),
country;