SELECT SUM() 基本用法和空值处理
SUM()只对数值列有效,遇到
NULL会自动跳过,不会报错,但也不会参与计算。如果整列都是
NULL,结果返回
NULL而不是
0—— 这是实际开发中最常踩的坑。 想把
NULL当
0算:用
COALESCE(column_name, 0)包一层,比如
SUM(COALESCE(price, 0))确认是否真有数据:加
COUNT(*)对比,比如
SELECT SUM(amount), COUNT(*) FROM orders,若后者远大于前者,说明存在大量
NULL值 别在
SUM()里直接写字符串或表达式如
SUM('1'),MySQL 会隐式转成 1,但语义混乱且不可靠
带 WHERE 和 GROUP BY 的 SUM 组合使用
单靠
SUM()很少单独出现,多数场景要配合过滤或分组。注意
WHERE在聚合前生效,
HAVING在聚合后筛选 —— 混用会导致逻辑错误。 查某类订单总金额:
SELECT SUM(total) FROM orders WHERE status = 'paid'按用户统计消费总额:
SELECT user_id, SUM(amount) FROM payments GROUP BY user_id只显示总金额超 1000 的用户:
SELECT user_id, SUM(amount) FROM payments GROUP BY user_id HAVING SUM(amount) > 1000(不能用
WHERE SUM(amount) > 1000)
浮点数精度问题与 DECIMAL 类型建议
如果字段是
FLOAT或
DOUBLE,
SUM()结果可能出现意外小数位,比如
0.1 + 0.2得到
0.30000000000000004。财务类统计必须避免。 建表时金额字段优先用
DECIMAL(10,2),
SUM()对
DECIMAL是精确计算 已有
FLOAT字段临时修复:用
ROUND(SUM(amount), 2),但只是掩盖问题,不解决根源 执行
SELECT SUM(amount) FROM table后,用
SELECT @@sql_mode检查是否启用了严格模式,某些模式下隐式转换可能触发警告
性能注意事项:索引与大表扫描
SUM()本身不走索引优化,MySQL 仍需扫描满足条件的行。当数据量大、又没合适索引时,响应明显变慢。 给
WHERE条件字段建索引,比如
WHERE category = 'A',就在
category上建索引 覆盖索引有用:如果查询只有
SUM(price)和
WHERE status,可建联合索引
(status, price),避免回表 避免在
SUM()中调用函数,如
SUM(IF(type='vip', amount, 0)),会强制全表扫描;改用
WHERE预过滤更高效 真正容易被忽略的是:SUM() 的返回类型继承自输入列,如果源字段是
INT,超大求和可能溢出变成负数;上线前务必用预估最大值反向验证字段类型是否足够宽。
