MySQL聚合函数可以对一组值进行计算并返回单个汇总结果,是数据统计类查询的核心工具,在报表生成、业务指标计算等场景中应用非常广泛。常用的聚合函数包含计数、求和、平均值、最值等不同类型,适配不同的统计需求。

MySQL常用聚合函数梳理
MySQL内置的聚合函数覆盖了大部分基础统计场景,以下是使用频率最高的几类:
- COUNT():统计符合条件的记录行数,可统计所有行或指定列的非空值数量
- SUM():计算指定列的数值总和,仅对数值类型列有效
- AVG():计算指定列的数值平均值,会自动忽略NULL值
- MAX()/MIN():分别返回指定列的最大值和最小值,支持数值、字符串、日期类型
- GROUP_CONCAT():将分组内的多个值拼接成单个字符串返回
基础聚合函数使用示例
先假设有一张用户订单表order_info,表结构如下:
-- 订单表结构
CREATE TABLE order_info (
order_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
goods_name VARCHAR(50) NOT NULL,
order_amount DECIMAL(10,2) NOT NULL,
order_status TINYINT NOT NULL COMMENT '1-待支付 2-已支付 3-已取消',
create_time DATETIME NOT NULL
);
以下是单个聚合函数的基础用法示例:
-- 统计订单总数量 SELECT COUNT(*) AS total_order FROM order_info; -- 统计已支付订单的总金额 SELECT SUM(order_amount) AS paid_total FROM order_info WHERE order_status = 2; -- 统计所有订单的平均金额 SELECT AVG(order_amount) AS avg_amount FROM order_info; -- 查询最早和最晚的订单创建时间 SELECT MIN(create_time) AS first_order, MAX(create_time) AS last_order FROM order_info;
结合GROUP BY的分组统计案例
聚合函数常和GROUP BY搭配实现分组统计,以下是两个典型业务场景:
案例1:统计每个用户的订单数量和总消费
需求是获取每个用户的下单次数和累计消费金额,按消费金额降序排列:
SELECT
user_id,
COUNT(order_id) AS order_count,
SUM(order_amount) AS total_consume
FROM order_info
WHERE order_status = 2 -- 只统计已支付订单
GROUP BY user_id
ORDER BY total_consume DESC;
案例2:统计不同状态订单的数量和占比
需求是统计各状态订单的数量,以及该状态订单占总订单的比例:
SELECT
order_status,
COUNT(*) AS status_count,
CONCAT(ROUND(COUNT(*) / (SELECT COUNT(*) FROM order_info) * 100, 2), '%') AS status_rate
FROM order_info
GROUP BY order_status;
结合HAVING的过滤统计案例
WHERE子句无法对聚合函数的结果进行过滤,此时需要使用HAVING子句,以下是实际案例:
案例:查询消费金额超过1000元的用户
SELECT
user_id,
SUM(order_amount) AS total_consume
FROM order_info
WHERE order_status = 2
GROUP BY user_id
HAVING total_consume > 1000
ORDER BY total_consume DESC;
特殊聚合函数GROUP_CONCAT使用案例
GROUP_CONCAT()可以将分组内的多个值拼接成字符串,适合需要展示分组内明细的场景:
案例:查询每个用户购买的所有商品名称
SELECT
user_id,
GROUP_CONCAT(goods_name SEPARATOR ',') AS bought_goods
FROM order_info
WHERE order_status = 2
GROUP BY user_id;
如果需要去重和排序,可以加上DISTINCT和ORDER BY参数:
SELECT
user_id,
GROUP_CONCAT(DISTINCT goods_name ORDER BY goods_name ASC SEPARATOR ',') AS bought_goods
FROM order_info
WHERE order_status = 2
GROUP BY user_id;
聚合函数使用注意事项
- 聚合函数会自动忽略列值为NULL的记录,如果需要把NULL算入统计,可以用
COALESCE()函数转换NULL为0 COUNT(*)统计所有行数,COUNT(列名)只统计该列非NULL的行数,两者结果可能不同- 使用
GROUP BY时,SELECT后面的列要么是聚合函数,要么必须出现在GROUP BY子句中,否则结果不符合预期 - 如果需要对分组后的结果过滤,必须用
HAVING而不是WHERE,WHERE是在分组前过滤数据