SQL 条件聚合 使用方法总结

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;

三、简写兼容写法

  1. MySQL专属 IF 替代CASE,写法更简短
sql 复制代码
SUM(IF(score>=60, score, 0))
COUNT(IF(gender='男',1,NULL))
  1. 空值特性:不满足条件返回NULL,聚合自动忽略

四、关键规则

  1. 满足条件取字段值,不满足默认返回NULL,聚合自动过滤空值
  2. 适合一行多指标统计,替代多次子查询,性能更高
  3. 可多层条件嵌套,实现区间分级统计
  4. 可和GROUP BYHAVING组合使用

五、区间统计实战

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;
相关推荐
ClouGence14 分钟前
保障公共安全,一线治安机构实时数据应用与实践
数据库·mysql·postgresql
烟漠河洛35 分钟前
线上事故复盘:Redis幂等性设计边界没覆盖跨状态请求,订单状态机直接崩了
数据库·redis·缓存
Minxinbb1 小时前
TDSQL for MySQL 服务器重启操作
数据库·mysql·dba
SelectDB1 小时前
Doris 实战:用 Colocate Join 消除 Shuffle,AB 指标计算性能提升 145 倍 🚀
数据库·性能优化·ab测试
PawSQL1 小时前
PawSQL 技术月报 | 2026年6月
数据库·sql·tdsql·pawsql·sql审核
SelectDB1 小时前
Apache Doris 在 AgentLogsBench 中领先,支撑 Agent 可观测性生产负载
运维·数据库·agent
聚美智数2 小时前
黄历查询-运势查询-国际法定节假日查询-API接口介绍
android·java·数据库
范什么特西3 小时前
网络代理问题
java·linux·服务器
夜影风4 小时前
Redis集群创建时出现“Node xxx.xxx is not empty”问题处理
数据库·redis·缓存
utf8mb4安全女神4 小时前
【Redis数据库】哨兵集群/redis集群/安装配置/主从复制/数据持久化操作/数据结构/安全限制/PHP redis/
linux·服务器·数据结构·数据库·redis·缓存