2.20 sql基础聚合函数(COUNT、SUM、AVG、MAX、MIN)
2026/4/16 21:31:46 网站建设 项目流程

2.20 基础聚合函数(COUNT、SUM、AVG、MAX、MIN)

在电商数据分析中,你几乎每天都要用到聚合函数:

  • 统计总订单数(COUNT)。

  • 计算总销售额(SUM)。

  • 求平均客单价(AVG)。

  • 找最高/最低金额(MAX/MIN)。

这一章我会带你彻底搞懂五个最常用的聚合函数:COUNTSUMAVGMAXMIN。学完之后,你能独立完成电商核心经营指标的一站式统计。

学习前准备:

  • 已完成MySQL安装(参考系列前几章)

  • 已安装DBeaver或Navicat

  • 准备一个练习数据库,比如agg_demo

学习前环境准备

步骤1:确保MySQL服务已启动。

步骤2:创建练习数据库和表,并插入示例数据。

CREATEDATABASEagg_demoCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci;USEagg_demo;-- 订单表CREATETABLEorders(order_idINTPRIMARYKEYAUTO_INCREMENT,user_idINTNOTNULL,shop_nameVARCHAR(50)NOTNULL,product_nameVARCHAR(100),amountDECIMAL(10,2)NOTNULL,quantityINTNOTNULLDEFAULT1,order_statusVARCHAR(20)NOTNULL,create_timeDATETIMENOTNULL);INSERTINTOorders(user_id,shop_name,product_name,amount,quantity,order_status,create_time)VALUES(1001,'女装旗舰店','碎花连衣裙',299.00,2,'已支付','2025-06-01 10:00:00'),(1002,'女装旗舰店','纯棉T恤',189.00,3,'已取消','2025-06-01 11:00:00'),(1003,'男装专营店','牛仔裤',599.00,1,'已支付','2025-06-02 09:30:00'),(1001,'女装旗舰店','雪纺衫',399.00,1,'已支付','2025-06-03 14:20:00'),(1004,'童装店','儿童T恤',99.00,5,'已完成','2025-06-03 16:00:00'),(1005,'女装旗舰店','真丝连衣裙',1299.00,1,'已支付','2025-06-04 08:30:00'),(1002,'男装专营店','休闲短裤',89.00,2,'已取消','2025-06-04 10:00:00'),(1006,'女装旗舰店','基础打底衫',89.00,10,'已支付','2025-06-05 09:00:00'),(1007,'男装专营店','Polo衫',259.00,1,'已支付','2025-06-05 14:00:00');

聚合函数基础认知

聚合函数对一组值执行计算,返回单个结果。它们通常与GROUP BY配合使用,也可以单独用于全表统计。

常用聚合函数

函数作用电商示例
COUNT()计数订单数、用户数
SUM()求和GMV、销量
AVG()平均值客单价、件单价
MAX()最大值最高订单金额
MIN()最小值最低商品售价
执行逻辑:聚合函数会在WHERE筛选之后、GROUP BY分组之后对每组进行计算。

我的踩坑经历:第一次用COUNT(*)时,我以为COUNT(column)COUNT(*)一样,后来发现COUNT(column)会忽略NULL值,导致计数偏少。从此我根据需求选择正确的形式。

COUNT函数详解(计数)

4.1 基础语法

COUNT(*)-- 统计所有行(包括NULL)COUNT(列名)-- 统计该列非NULL的行数COUNT(DISTINCT列名)-- 统计去重后的数量

4.2 电商实操案例

案例一:统计总订单数

SELECTCOUNT(*)AStotal_ordersFROMorders;

预期结果:9。

案例二:统计已支付订单数

SELECTCOUNT(*)ASpaid_ordersFROMordersWHEREorder_status='已支付';

预期结果:6(ORD001、ORD003、ORD004、ORD006、ORD008、ORD009)。

案例三:统计有商品名称的订单数(排除NULL)

假设没有NULL,演示用法。

SELECTCOUNT(product_name)AShas_product_nameFROMorders;

案例四:统计独立用户数(去重)

SELECTCOUNT(DISTINCTuser_id)ASunique_usersFROMorders;

预期结果:7(1001,1002,1003,1004,1005,1006,1007)。

4.3 分步操作

  1. 确定要统计的对象(所有行、某列非空、去重)。

  2. 加上WHERE条件(如果需要)。

  3. 执行并验证。

避坑提醒

  • COUNT(*)COUNT(1)性能几乎相同,推荐用COUNT(*)

  • COUNT(column)会忽略NULL,如果不确定是否有NULL,用COUNT(*)更安全。

实操避坑提醒:统计用户数时,必须用COUNT(DISTINCT user_id),否则同一用户多单会被重复计数。

SUM函数详解(求和)

5.1 基础语法

SUM(列名)-- 对数值列求和,自动忽略NULL

5.2 电商实操案例

案例一:计算全店GMV(已支付订单总金额)

SELECTSUM(amount)ASgmvFROMordersWHEREorder_status='已支付';

预期结果:299+599+399+1299+89+259 = 2944? 计算:299+599=898,+399=1297,+1299=2596,+89=2685,+259=2944。正确。

案例二:计算女装旗舰店的总销量(数量)

SELECTSUM(quantity)AStotal_quantityFROMordersWHEREshop_name='女装旗舰店';

预期结果:2+3+1+1+10 = 17? 注意ORD002是已取消但数量也计入?通常只计有效订单,需要加order_status条件。

SELECTSUM(quantity)AStotal_quantityFROMordersWHEREshop_name='女装旗舰店'ANDorder_status='已支付';

预期结果:ORD001(2), ORD004(1), ORD006(1), ORD008(10) = 14。

案例三:计算退款总金额(假设退款订单状态为“已取消”)

SELECTSUM(amount)ASrefund_amountFROMordersWHEREorder_status='已取消';

预期结果:189+89=278。

5.3 分步操作

  1. 筛选有效订单(WHERE)。

  2. 对需要求和的列使用SUM

  3. 执行验证。

避坑提醒

  • SUM自动忽略NULL,但不会忽略字符串。确保列是数值类型。

  • 对金额列求和时,注意单位一致(如都是元)。

我的踩坑经历:我写过SUM(amount),结果amount列里混了一个文本“N/A”,导致整个求和结果为NULL。从那以后,我每次都会先检查数据类型。

AVG函数详解(平均值)

6.1 基础语法

AVG(列名)-- 对数值列求平均值,自动忽略NULL

6.2 电商实操案例

案例一:计算全店平均客单价(已支付订单的平均金额)

SELECTAVG(amount)ASavg_order_valueFROMordersWHEREorder_status='已支付';

预期结果:2944 / 6 ≈ 490.67。

案例二:计算女装旗舰店已支付订单的平均件单价(金额/数量?这里简化:平均每笔订单金额)

SELECTAVG(amount)FROMordersWHEREshop_name='女装旗舰店'ANDorder_status='已支付';

预期结果:(299+399+1299+89)/4 = 2086/4=521.5。

案例三:计算每个用户平均下单金额(需配合GROUP BY,但这里先演示整体)

SELECTAVG(amount)FROMordersWHEREorder_status='已支付';

6.3 分步操作

  1. 筛选数据。

  2. AVG计算。

  3. 执行验证。

避坑提醒

  • AVG只对数值列有效。

  • AVG会忽略NULL,但不会忽略0。0会拉低平均值,要根据业务决定是否排除。

实操避坑提醒:客单价 = GMV / 订单数,不等于AVG(amount)吗?是的,因为AVG(amount)就是总金额除以订单数。但如果订单有多个商品,amount已经是订单总金额,那么AVG(amount)就是客单价。

MAX/MIN函数详解(最大/最小值)

7.1 基础语法

MAX(列名)-- 最大值MIN(列名)-- 最小值

7.2 电商实操案例

案例一:找出最高订单金额

SELECTMAX(amount)ASmax_amountFROMorders;

预期结果:1299。

案例二:找出最低订单金额(已支付订单)

SELECTMIN(amount)ASmin_amountFROMordersWHEREorder_status='已支付';

预期结果:89(ORD008)。

案例三:找出最早和最晚的下单时间

SELECTMIN(create_time)ASfirst_order,MAX(create_time)ASlast_orderFROMorders;

预期结果:2025-06-01 10:00:00 和 2025-06-05 14:00:00。

案例四:在商品表中找出最高和最低价格(假设有商品表)

-- 创建商品表CREATETABLEproducts(product_idINTPRIMARYKEY,product_nameVARCHAR(100),priceDECIMAL(10,2));INSERTINTOproductsVALUES(1,'连衣裙',299),(2,'T恤',89),(3,'牛仔裤',199);SELECTMAX(price),MIN(price)FROMproducts;

7.3 分步操作

  1. 筛选条件(可选)。

  2. MAXMIN

  3. 执行验证。

避坑提醒

  • MAX/MIN对文本列按字典序比较。

  • 对日期列也能正确比较。

我的踩坑经历:我用MAX(product_name)找最晚的商品名称,结果返回了字典序最大的,不是按时间。排序和聚合要分清。

多个聚合函数的组合用法

8.1 基础语法

可以在一个SELECT中同时使用多个聚合函数,得到一站式统计。

SELECTCOUNT(*)AStotal_orders,SUM(amount)ASgmv,AVG(amount)ASavg_price,MAX(amount)ASmax_price,MIN(amount)ASmin_priceFROMordersWHEREorder_status='已支付';

8.2 电商实操案例

案例一:全店经营核心指标(已支付订单)

SELECTCOUNT(*)ASorder_cnt,SUM(amount)ASgmv,ROUND(AVG(amount),2)ASavg_order_value,MAX(amount)ASmax_order,MIN(amount)ASmin_orderFROMordersWHEREorder_status='已支付';

预期结果:order_cnt=6, gmv=2944, avg_order_value=490.67, max=1299, min=89。

案例二:女装旗舰店的销售汇总

SELECTCOUNT(*)ASorders,SUM(amount)ASgmv,SUM(quantity)ASitems_sold,AVG(amount)ASavg_price,MAX(amount)AShighest,MIN(amount)ASlowestFROMordersWHEREshop_name='女装旗舰店'ANDorder_status='已支付';

预期结果:orders=4, gmv=2086, items_sold=14, avg_price=521.5, highest=1299, lowest=89。

案例三:按店铺分组统计(预告下一章内容,这里简单展示)

SELECTshop_name,COUNT(*)ASorder_cnt,SUM(amount)ASgmvFROMordersWHEREorder_status='已支付'GROUPBYshop_name;

8.3 分步操作

  1. 确定要统计的指标。

  2. 写出所有聚合函数,给别名。

  3. 添加WHERE条件(可选)。

  4. 执行并验证。

避坑提醒

  • 聚合函数不能与普通列混用(除非有GROUP BY)。例如SELECT order_id, COUNT(*) FROM orders会报错。

  • 多个聚合函数互相独立,计算顺序不影响结果。

实操避坑提醒:在计算平均值前,如果要去除异常值,可以在WHERE中先过滤。例如WHERE amount BETWEEN 10 AND 10000

综合实操案例:服饰类目店铺月度经营核心指标统计

9.1 案例背景

某服饰类目店铺需要生成一份6月份的经营汇总报表,包含以下指标:

  • 总订单数(所有状态)。

  • 有效订单数(已支付+已完成)。

  • GMV(已支付+已完成的金额总和)。

  • 客单价(GMV / 有效订单数)。

  • 最高订单金额、最低订单金额。

  • 总销量(数量总和,有效订单)。

  • 独立用户数(去重)。

9.2 分步操作

步骤1:总订单数

SELECTCOUNT(*)AStotal_ordersFROMordersWHEREcreate_timeBETWEEN'2025-06-01'AND'2025-06-30';

步骤2:有效订单数

SELECTCOUNT(*)ASvalid_ordersFROMordersWHEREorder_statusIN('已支付','已完成')ANDcreate_timeBETWEEN'2025-06-01'AND'2025-06-30';

步骤3:GMV

SELECTSUM(amount)ASgmvFROMordersWHEREorder_statusIN('已支付','已完成')ANDcreate_timeBETWEEN'2025-06-01'AND'2025-06-30';

步骤4:客单价

SELECTROUND(SUM(amount)/COUNT(*),2)ASavg_order_valueFROMordersWHEREorder_statusIN('已支付','已完成')ANDcreate_timeBETWEEN'2025-06-01'AND'2025-06-30';

步骤5:最高/最低订单金额(有效订单)

SELECTMAX(amount)ASmax_amount,MIN(amount)ASmin_amountFROMordersWHEREorder_statusIN('已支付','已完成')ANDcreate_timeBETWEEN'2025-06-01'AND'2025-06-30';

步骤6:总销量(有效订单的数量总和)

SELECTSUM(quantity)AStotal_itemsFROMordersWHEREorder_statusIN('已支付','已完成')ANDcreate_timeBETWEEN'2025-06-01'AND'2025-06-30';

步骤7:独立用户数(有效订单)

SELECTCOUNT(DISTINCTuser_id)ASunique_usersFROMordersWHEREorder_statusIN('已支付','已完成')ANDcreate_timeBETWEEN'2025-06-01'AND'2025-06-30';

步骤8:一站式查询(组合)

SELECTCOUNT(*)AStotal_orders,SUM(CASEWHENorder_statusIN('已支付','已完成')THEN1ELSE0END)ASvalid_orders,SUM(CASEWHENorder_statusIN('已支付','已完成')THENamountELSE0END)ASgmv,ROUND(SUM(CASEWHENorder_statusIN('已支付','已完成')THENamountELSE0END)/NULLIF(SUM(CASEWHENorder_statusIN('已支付','已完成')THEN1ELSE0END),0),2)ASavg_order_value,MAX(CASEWHENorder_statusIN('已支付','已完成')THENamountELSENULLEND)ASmax_amount,MIN(CASEWHENorder_statusIN('已支付','已完成')THENamountELSENULLEND)ASmin_amount,SUM(CASEWHENorder_statusIN('已支付','已完成')THENquantityELSE0END)AStotal_items,COUNT(DISTINCTCASEWHENorder_statusIN('已支付','已完成')THENuser_idEND)ASunique_usersFROMordersWHEREcreate_timeBETWEEN'2025-06-01'AND'2025-06-30';

9.3 结果验证

执行一站式查询,检查数据逻辑(如客单价 = GMV / 有效订单数)。

📌 电商数据合规提示:在统计独立用户数时,使用内部匿名user_id,不要涉及手机号等敏感信息。汇总指标(如GMV、客单价)属于经营数据,内部共享时注意权限控制。

本章踩坑清单与合规总结

10.1 新手常见踩坑

错误原因正确做法
COUNT(column)忽略NULL导致计数偏少不理解NULL处理COUNT(*)或确保列非空
金额列包含非数字字符求和结果为0或NULL先清洗数据,转换类型
AVG包含0值0拉低平均值根据业务决定是否排除0
聚合函数与普通列混用无GROUP BY语法错误要么全聚合,要么加GROUP BY
SUM(amount)未过滤无效订单统计了退款订单WHERE order_status = '已支付'

10.2 性能优化建议

  • WHERE条件中的列(如create_timeorder_status)建立索引。

  • 避免在聚合函数中使用DISTINCT处理大数据量,可先用子查询去重。

10.3 电商数据合规红线

  • 统计指标不要包含个人标识:如统计用户数时,只输出数字,不输出用户ID列表。

  • GMV等核心指标:内部报表需加密传输,避免泄露。

  • 退款金额统计:注意区分“退款”和“取消”,业务定义要清晰。

结语

聚合函数是SQL统计分析的基石。掌握COUNTSUMAVGMAXMIN,你就能独立计算电商核心经营指标。

有问题的评论区留言,我看到会回复。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询