COUNT统计行数,SUM计算数值列总和;COUNT(*)统计所有行,COUNT(列名)仅统计非NULL值,SUM自动忽略NULL且返回NULL而非0。

COUNT 和 SUM 是 SQL 中最常用、也最容易混淆的两个聚合函数:COUNT 统计“有多少行”,SUM 计算“某列数值加起来是多少”。用错场景或忽略 NULL,结果就容易出偏差。
COUNT 的三种写法,效果完全不同
COUNT(*) 统计所有行(包括含 NULL 的行);COUNT(列名) 只统计该列非 NULL 的行;COUNT(1) 等价于 COUNT(*),是写法习惯,性能无实质差别。
- 查用户总数(含未填年龄的)→ SELECT COUNT(*) FROM users;
- 查填了手机号的用户数 → SELECT COUNT(phone) FROM users;
- 查订单表里 status 不为 NULL 的订单数 → SELECT COUNT(status) FROM orders;
SUM 只对数值列有效,且自动跳过 NULL
SUM 不会报错,但也不会把 NULL 当 0 加。如果一列全是 NULL,SUM 返回 NULL 而不是 0;需要默认值时,得配合 COALESCE 或 IFNULL。
- 算全部订单金额总和(空金额不参与)→ SELECT SUM(amount) FROM orders;
- 想让空金额按 0 计算 → SELECT SUM(COALESCE(amount, 0)) FROM orders;
- 查每个用户的消费总额(没下单则显示 0)→ SELECT user_id, COALESCE(SUM(amount), 0) FROM orders GROUP BY user_id;
组合使用 COUNT 和 SUM,解决实际业务问题
比如分析销售数据:既要知道“有多少单”,也要知道“卖了多少钱”,还要算“平均每单多少”——这时候别用 AVG(amount),它会跳过 NULL,但更关键的是,它和 COUNT(*) 不是一回事。
- 正确计算平均订单金额(按实际订单数)→ SELECT COUNT(*) AS order_count, SUM(amount) AS total, ROUND(SUM(amount)/COUNT(*), 2) AS avg_per_order FROM orders WHERE amount IS NOT NULL;
- 查各城市用户数和总充值金额 → SELECT city, COUNT(*) AS user_cnt, SUM(recharge) AS total_recharge FROM users GROUP BY city;
- 筛选出至少下过 3 单且总金额超 500 的用户 → SELECT user_id FROM orders GROUP BY user_id HAVING COUNT(*) >= 3 AND SUM(amount) > 500;
基本上就这些。用熟 COUNT 和 SUM,再搭配 GROUP BY、HAVING、COALESCE,大部分汇总需求都能稳住。










