mysql如何使用聚合函数_mysqlsum avg min max等函数讲解

来源:这里教程网 时间:2026-02-28 20:50:55 作者:

sum、avg、min、max 必须配合 GROUP BY 吗?

不是必须,但绝大多数场景下不加

GROUP BY
就只能得到全表聚合结果。比如
SELECT SUM(price) FROM orders;
会返回一张表的总金额,而不是每条记录都重复这个值——它天然压缩行数。如果你在没
GROUP BY
的情况下还写了其他非聚合字段(如
SELECT id, SUM(price) FROM orders;
),MySQL 8.0+ 默认报错:
Expression #1 of SELECT list is not in GROUP BY clause
,因为
id
没有明确归属逻辑。

常见误操作:

漏写
GROUP BY
却期望按用户分组求平均,结果只返回一行
ANY_VALUE()
绕过错误,却不理解它只是随机取值,掩盖语义问题
在 WHERE 中误用聚合函数,比如
WHERE SUM(amount) > 100
—— 这是语法错误,得改用
HAVING SUM(amount) > 100

count(*) 和 count(字段) 的行为差异

COUNT(*)
统计行数,包括含
NULL
的行;
COUNT(字段)
只统计该字段非
NULL
的行数。这在处理可空字段(如
email
phone
)时直接影响结果。

例如:

SELECT COUNT(*), COUNT(email), COUNT(phone) FROM users;

如果 100 条记录里有 12 条

email
NULL
,那
COUNT(email)
返回 88;若
phone
有 30 条为
NULL
,则
COUNT(phone)
是 70。

注意:

COUNT(1)
COUNT(*)
在 MySQL 中执行计划几乎一致,性能无实质差别,别迷信“
COUNT(1)
更快”这种过时说法。

avg 和 sum 对 NULL 的处理方式

AVG()
SUM()
都自动忽略
NULL
值,不会报错也不会把
NULL
当 0 算。但容易被忽略的是:如果整列全是
NULL
AVG()
返回
NULL
SUM()
也返回
NULL
(不是 0)。

实操建议:

需要默认值时,用
COALESCE(AVG(score), 0)
显式转成 0
避免在业务逻辑里直接判
IS NULL
,而应提前在 SQL 层补缺,减少应用层分支
AVG()
内部先求和再除以非
NULL
行数,所以
AVG(x)
SUM(x)/COUNT(*)
(后者会因分母含
NULL
行而出错)

聚合函数嵌套的限制与替代方案

MySQL 不支持直接嵌套聚合函数,比如

AVG(MAX(price))
SUM(COUNT(*))
会报错:
Invalid use of group function
。这不是语法疏漏,而是语义冲突:外层聚合无法确定内层的分组上下文。

可行路径只有两种:

用子查询拆开:先在子查询中算出每组的
MAX(price)
,外层再
AVG()
用窗口函数替代(MySQL 8.0+):如
AVG(MAX(price)) OVER ()
是非法的,但
MAX(price) OVER (PARTITION BY category)
+ 外层聚合可间接实现

最常踩的坑是试图用

HAVING
过滤聚合结果后再聚合,结果发现
HAVING
之后不能再接聚合——本质还是单层聚合限制。真要多级汇总,得靠临时表或 CTE。

相关推荐