MySQL聚合查询:COUNT、SUM、AVG用法,实战案例演示

前言

日常开发中,我们经常需要对数据进行「统计分析」,比如:统计用户总数、计算平均年龄、求和订单金额,这时候就需要用到 MySQL 聚合函数。

最常用的聚合函数有3个:COUNT(计数)、SUM(求和)、AVG(求平均),本篇用实战案例,讲透每个函数的用法、场景和避坑点,新手能直接套用。

继续使用前面的user表,新增一张订单表(增加实战场景):

sql 复制代码
-- 创建订单表 order(注意order是关键字,用反引号包裹)
CREATE TABLE `order` (
    order_id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT,  -- 关联用户表主键
    amount DECIMAL(10,2),  -- 订单金额(保留2位小数)
    create_time DATETIME DEFAULT NOW()
);
sql 复制代码
-- 插入订单测试数据
INSERT INTO `order` (user_id, amount) 
VALUES 
(1, 99.90),
(1, 199.90),
(2, 59.90),
(3, 299.90),
(4, 159.90),
(4, 89.90);

一、COUNT:计数(最常用)

核心作用:统计符合条件的「记录条数」,有3种常用写法,重点区分差异。

1. COUNT(*)

统计所有记录条数,包括 NULL 值(最常用、效率最高)。

sql 复制代码
-- 1. 统计用户总数
SELECT COUNT(*) AS user_total FROM user;

-- 2. 统计性别为男的用户数
SELECT COUNT(*) AS male_total FROM user WHERE gender = 1;

-- 3. 统计订单总数
SELECT COUNT(*) AS order_total FROM `order`;

2. COUNT(字段名)

统计该字段「非NULL值」的记录条数,忽略NULL值。

sql 复制代码
-- 统计age字段非NULL的用户数(如果有用户age为NULL,会被排除)
SELECT COUNT(age) AS age_not_null FROM user;

3. COUNT(DISTINCT 字段名)

统计该字段「非NULL且不重复」的记录条数。

sql 复制代码
-- 统计有订单的不同用户数(一个用户可能有多个订单,只算1次)
SELECT COUNT(DISTINCT user_id) AS user_with_order FROM `order`;

COUNT避坑

❌ 错误:用COUNT(字段名)统计总条数,忽略了NULL值,导致统计结果偏小;

✅ 正确:统计总条数优先用 COUNT(*),统计非NULL字段用 COUNT(字段名)。


二、SUM:求和

核心作用:对指定「数值类型字段」求和,忽略NULL值,非数值类型求和会返回0。

sql 复制代码
-- 1. 统计所有订单的总金额
SELECT SUM(amount) AS total_amount FROM `order`;

-- 2. 统计用户id=1的所有订单金额总和
SELECT SUM(amount) AS user1_total FROM `order` WHERE user_id = 1;

-- 3. 非数值字段求和(返回0,无意义)
SELECT SUM(name) AS wrong_sum FROM user;

SUM避坑

❌ 错误:对非数值字段(如name、email)使用SUM,结果无意义;

✅ 正确:SUM仅用于数值类型字段(int、decimal等)。


三、AVG:求平均

核心作用:对指定「数值类型字段」求平均值,忽略NULL值,计算逻辑:总和 ÷ 非NULL记录数。

sql 复制代码
-- 1. 计算所有用户的平均年龄
SELECT AVG(age) AS avg_age FROM user;

-- 2. 计算所有订单的平均金额(保留2位小数,用ROUND函数)
SELECT ROUND(AVG(amount), 2) AS avg_amount FROM `order`;

-- 3. 计算性别为女的用户平均年龄
SELECT AVG(age) AS female_avg_age FROM user WHERE gender = 2;

AVG避坑

❌ 错误:忽略NULL值的影响,比如部分用户age为NULL,会导致平均年龄计算偏差;

✅ 正确:如果需要包含NULL值(按0计算),可搭配IFNULL函数:SELECT AVG(IFNULL(age, 0)) FROM user;


四、聚合查询实战案例

需求:统计有订单的用户中,年龄大于20的用户数、他们的平均年龄、以及他们的订单总金额。

sql 复制代码
SELECT 
    COUNT(DISTINCT u.id) AS target_user,  -- 符合条件的用户数
    ROUND(AVG(u.age), 2) AS avg_age,      -- 平均年龄
    SUM(o.amount) AS total_order_amount   -- 订单总金额
FROM user u
LEFT JOIN `order` o ON u.id = o.user_id  -- 关联用户表和订单表
WHERE u.age > 20 AND o.user_id IS NOT NULL;  -- 有订单且年龄>20

五、总结

  1. COUNT:计数,优先用COUNT(*),统计非NULL用COUNT(字段),去重计数用COUNT(DISTINCT 字段);

  2. SUM:对数值字段求和,忽略NULL,非数值字段返回0;

  3. AVG:对数值字段求平均,忽略NULL,可搭配ROUND函数保留小数。

相关推荐
素材积累4 小时前
博士后出站来深可申请的项目补贴等
数据库
_1_76 小时前
SQL Server 磁盘满了 收缩日志
数据库·sqlserver
basketball6166 小时前
Redis基础:1. Redis介绍
数据库·redis·缓存
艾iYYY6 小时前
string 类的模拟实现
android·服务器·c语言·c++·算法
李可以量化6 小时前
成交量的终极量化策略:价量共振指标完整实现(下篇)
前端·数据库·人工智能
xyzzklk7 小时前
解决Salesforce无法向外发送邮件
android·java·开发语言·网络·crm·salesforce·客户关系管理
汽车仪器仪表相关领域7 小时前
南华 NHAT-610 柴油车排放测试仪 产品详解
数据库·功能测试·汽车·压力测试·可用性测试
修炼者9 小时前
Gradle三阶段
android
我滴老baby9 小时前
工业时序数据实战:基于 DolphinDB 流计算引擎的实现与调优
数据库
睡不醒男孩0308239 小时前
TiDB数据库调研
数据库·tidb