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

相关推荐
GuWenyue2 小时前
Cursor黑盒拆解!1套LangChain.js手写Mini编程Agent,自动生成React项目,效率提升60%
前端·数据库·人工智能
GitLqr2 小时前
Flutter 无障碍开发实战:玩转 Semantics 解决视障用户使用痛点
android·flutter·dart
Miao121314 小时前
某海外住宿平台如何在大规模场景下实现指标一致性:Minerva 指标平台实践
大数据·数据库·人工智能
CodexDave4 小时前
MySQL事务隔离级别与MVCC机制解析
前端·数据库·mysql·nginx·性能优化·负载均衡
碎光拾影4 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
曾阿伦4 小时前
MongoDB 查询语句备忘手册
数据库·mongodb
一叶龙洲4 小时前
wslg打开Ubuntu24.04默认打开图形界面
linux·服务器·数据库·ubuntu
CCPC不拿奖不改名4 小时前
大模型推理架构与开源生态知识整理
数据库·windows·python·架构·langchain·开源·github
雨白6 小时前
掌握 NestedScrolling 嵌套滑动:手写仿知乎折叠主页
android
爬也要爬着前进6 小时前
redis主从搭建
数据库·redis·缓存