SQL 条件聚合 使用方法总结
核心:聚合函数 + 条件判断,分组内按条件统计不同维度数据
一、核心语法
-- 基础格式聚合函数(CASEWHEN条件THEN字段END)别名常用聚合:SUM/COUNT/AVG/MAX/MIN
二、常用场景&示例
1. 条件求和 SUM
按条件累加指定数据
-- 统计男、女各自薪资总和SELECTSUM(CASEWHENgender='男'THENsalaryEND)ASman_sal,SUM(CASEWHENgender='女'THENsalaryEND)ASwoman_salFROMstaff;2. 条件计数 COUNT
统计符合条件的记录数
-- 统计及格、不及格人数SELECTCOUNT(CASEWHENscore>=60THEN1END)ASpass_num,COUNT(CASEWHENscore<60THEN1END)ASfail_numFROMexam;3. 条件平均值 AVG
只计算满足条件数据的均值
-- 计算正式员工平均工资SELECTAVG(CASEWHENstatus=1THENsalaryEND)FROMstaff;4. 搭配 GROUP BY 分组条件聚合
分组后再细分条件统计
-- 按部门分组,统计部门男女人数SELECTdept,COUNT(CASEWHENgender='男'THEN1END)ASman_cnt,COUNT(CASEWHENgender='女'THEN1END)ASwoman_cntFROMstaffGROUPBYdept;三、简写兼容写法
- MySQL专属
IF替代CASE,写法更简短
SUM(IF(score>=60,score,0))COUNT(IF(gender='男',1,NULL))- 空值特性:不满足条件返回NULL,聚合自动忽略
四、关键规则
- 满足条件取字段值,不满足默认返回NULL,聚合自动过滤空值
- 适合一行多指标统计,替代多次子查询,性能更高
- 可多层条件嵌套,实现区间分级统计
- 可和
GROUP BY、HAVING组合使用
五、区间统计实战
-- 统计不同分数段人数SELECTCOUNT(CASEWHENscore<60THEN1END)ASlow,COUNT(CASEWHENscoreBETWEEN60AND80THEN1END)ASmid,COUNT(CASEWHENscore>80THEN1END)AShighFROMexam;六、速记口诀
条件套进聚合里,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 |
SELECTDATE_FORMAT(trans_date,'%Y-%m')ASmonth,country,COUNT(*)AStrans_count,SUM(amount)AStrans_total_amount,SUM(CASEWHENstate='approved'THEN1ELSE0END)ASapproved_count,SUM(CASEWHENstate='approved'THENamountELSE0END)ASapproved_total_amountFROMTransactionsGROUPBYDATE_FORMAT(trans_date,'%Y-%m'),country;