mysql支持在一条select中用sum()、avg()、max()等同时计算多个聚合值,但需注意null处理、group by规则、索引优化及空结果返回null等关键细节。

用 SUM()、AVG()、MAX() 一次性算多个聚合值
MySQL 支持在一条 SELECT 语句里同时调用多个聚合函数,不需要拆成多条查询。只要字段类型兼容(比如数值型),就能直接并列写:
SELECT SUM(price) AS total, AVG(price) AS avg_price, MAX(price) AS highest FROM products;
注意:AVG() 和 SUM() 会自动跳过 NULL 值,但若整列全为 NULL,AVG() 返回 NULL 而非 0;MAX() 同样返回 NULL。
- 如果想把
NULL当作 0 参与计算,得先用COALESCE(price, 0)包一层 - 聚合函数不能直接和普通字段混用(比如
SELECT name, MAX(price)),除非加GROUP BY name,否则报错ERROR 1140: In aggregated query without GROUP BY - 对大表执行时,确保
price字段有索引,否则MAX()可能触发全表扫描
按分组分别求和、平均、最大值
用 GROUP BY 配合聚合函数,可对每个分组独立计算。常见于统计各分类销量、各地区均价等场景:
SELECT category, SUM(sales), AVG(sales), MAX(sales) FROM orders GROUP BY category;
关键点:
-
SELECT中所有非聚合字段(如category)都必须出现在GROUP BY列表中,否则 MySQL 8.0+ 默认拒绝执行(sql_mode含ONLY_FULL_GROUP_BY) - 若某组内所有
sales值都是NULL,该组的AVG()和SUM()结果为NULL,MAX()也是NULL - 想过滤掉聚合结果为
NULL的组,不能用WHERE sales IS NOT NULL(那是过滤行),得用HAVING SUM(sales) IS NOT NULL
处理空结果集时的陷阱
当 WHERE 条件没匹配到任何行,SUM()、AVG()、MAX() 全部返回 NULL,不是 0 或空字符串:
SELECT AVG(score) FROM students WHERE id = 999999;
返回单行 NULL,而非无结果。这容易导致应用层空指针或逻辑误判。安全做法是:
- 用
COALESCE(AVG(score), 0)显式转为 0(注意:0 和 NULL 语义不同,别盲目替换) - 在应用代码里检查查询结果是否为
null,而不是只判断是否有数据行 - 避免用
IFNULL(MAX(id), 0) + 1做自增 ID 生成——并发下可能重复,这不是原子操作
性能与精度要注意的细节
AVG() 内部是先 SUM() 再除以 COUNT(),所以大数相加可能溢出 DECIMAL 或 BIGINT 范围;MAX() 虽快,但若字段无索引且数据量大,仍很慢:
-
AVG(price)等价于SUM(price)/COUNT(price),但前者更简洁,且 MySQL 会做内部优化 - 对
DECIMAL字段求平均时,结果精度由字段定义决定(如DECIMAL(10,2)的AVG()默认保留 2 位小数),必要时用ROUND(AVG(price), 4)控制 -
MAX()在有索引的列上走索引 B-Tree 最右节点,极快;但如果是MAX(ABS(price))这种表达式,无法利用索引,只能全表扫描
聚合函数看着简单,但空值语义、分组约束、索引失效、精度截断这些地方,一不留神就出错。











