count()默认忽略null值,只统计非null行;count()、count(1)等统计所有行;统计null需用count()-count(字段)或case when;空字符串、0等不等于null。

COUNT() 默认忽略 NULL 值,不会把 NULL 当作一条记录统计。这是 SQL 标准行为,也是初学者最容易误解的地方:看到表里有“空”数据就以为 COUNT 会算进去,结果发现总数对不上。
为什么 COUNT(字段) 不统计 NULL?
COUNT(字段) 只统计该字段值非 NULL的行。数据库在执行时会逐行检查该字段是否为 NULL,跳过所有 NULL 行,仅对有效值计数。
- 例如:
COUNT(age)不会统计 age 是 NULL 或空字符串('')的记录(注意:空字符串不是 NULL,但若 age 是数值类型,'' 通常转为 NULL 或报错) -
COUNT(*)是例外——它统计所有行,不管任何字段是否为 NULL -
COUNT(1)、COUNT(任意常量)效果等同于COUNT(*),也统计全部行
想把 NULL 也算作一种情况,怎么统计?
不能直接用 COUNT(字段),需改用条件聚合:
- 统计 NULL 的数量:
COUNT(*) - COUNT(字段)或SUM(CASE WHEN 字段 IS NULL THEN 1 ELSE 0 END) - 分组统计 NULL 和非 NULL:
GROUP BY CASE WHEN 字段 IS NULL THEN 'NULL' ELSE 'NOT NULL' END - 同时查出非空数、空数、总数:
SELECTCOUNT(*) AS total,COUNT(name) AS not_null_count,COUNT(*) - COUNT(name) AS null_countFROM users;
常见误区提醒
- 空字符串('')、数字 0、字符串 'NULL' 都不等于 SQL 中的 NULL,COUNT 不会忽略它们(除非字段类型强制转换失败导致隐式转为 NULL)
- 使用
COUNT(DISTINCT 字段)时,NULL 仍被忽略,且多个 NULL 视为同一值,只算一次(标准行为,但部分数据库如 MySQL 8.0+ 明确规定 DISTINCT 中 NULL 只出现一次) - WHERE 条件中判断 NULL 必须用
IS NULL或IS NOT NULL,不能用= NULL或!= NULL










