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函数保留小数。

相关推荐
驰骋工作流1 小时前
流程时效考核的表结构:从待办时限到 WF_CH 考核结果驰骋BPM驰骋低代码低代码工作流引擎
android·低代码·rxjava
小徐不徐说3 小时前
C++ 接口与插件设计:从工厂注册到 Qt 动态插件
数据库·c++·qt·系统架构·程序设计
传奇开心果编程3 小时前
【Flutter踩坑排雷】第7课:巨型 build 函数坑|全部 UI 写在同一个 build,维护难、隐性异常
android·flutter·ios·移动开发·跨平台·dart·声明式ui
论文复现现场3 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
Decay__4 小时前
04_MySQL DBA 日常运维手册 —— 会话管理、锁与阻塞、事务监控、慢查询与日志巡检
运维·数据库·sql·mysql·架构
心梦缘-雪雁6 小时前
SQL Server 查询数据存在哪个表里
数据库
lusklusklusk6 小时前
Python 巡检脚本:进程运行状态、数据库写入时效检查及邮件通知与告警
数据库·python·oracle
GeW7 小时前
产业新优势基础软件的人才底盘,从Linux与数据库开始
linux·数据库
方白羽7 小时前
Android 双开环境底层剖析与风控检测落地
android·安全·app
SelectDB7 小时前
Doris Arrow Flight SQL 高速读取协议实战:与 Snowflake 客户端取数链路对照
大数据·数据库·数据分析