标准写法是col IS NOT NULL:它非函数、不可加括号,WHERE col != NULL或= NULL均无效;IS NOT NULL可走索引(需列允许NULL),而COALESCE/IFNULL用于值替换,不可替代筛选逻辑。

WHERE里写col IS NOT NULL才是标准写法
MySQL中判断“非空”只有一种可靠方式:col IS NOT NULL。它不是函数,不能加括号,也不能写成ISNOTNULL(col)或IS NOT NULL(col)——这些语法要么报错,要么被当成无效表达式。
常见错误现象:
-
WHERE col != NULL或WHERE col NULL:永远不匹配任何行,因为NULL参与的任何比较都返回UNKNOWN,而非TRUE -
WHERE col = NULL:同理,结果恒为空集 -
WHERE ISNULL(col) = 0:虽然能凑合用,但语义绕、性能差,且ISNULL()是函数调用,无法走索引优化
正确写法就一条:SELECT * FROM users WHERE email IS NOT NULL。它清晰、标准、可被优化器识别。
IS NOT NULL能走索引,但前提是列允许NULL
只要字段定义时没加NOT NULL约束,且该列上有普通B+树索引(单列或联合索引最左前缀),IS NOT NULL就能利用索引扫描,类型通常是range或ref。
验证方法很简单:
- 运行
EXPLAIN SELECT * FROM product WHERE category_id IS NOT NULL - 看输出中
key是否显示索引名,rows是否明显小于全表行数 - 如果
category_id定义为NOT NULL,优化器可能直接标记Impossible WHERE,因为条件永真,无需过滤
注意:联合索引中,IS NOT NULL只对最左列有效;若写成WHERE a IS NOT NULL AND b = 1,而索引是(a,b),那可以走索引;但反过来就不行。
和COALESCE()、IFNULL()混用时别搞错目的
IS NOT NULL是逻辑判断,用于过滤或条件分支;COALESCE()和IFNULL()是值替换函数,用于兜底或拼接。两者用途不同,不能互相替代。
典型误用场景:
- 想查“描述不为空”的产品,却写
WHERE COALESCE(description, '') != '':绕远、无法走索引、字符串比较还可能受字符集影响 - 在
ORDER BY里用COALESCE(price, 0)排序没问题,但千万别拿它代替price IS NOT NULL做筛选 -
CONCAT(first_name, ' ', last_name)结果为NULL,是因为任一参数为NULL——这时要用COALESCE(first_name, '')预处理,而不是在WHERE里硬套IS NOT NULL
记住:筛选用IS NOT NULL,补空用COALESCE(),二者各司其职。
聚合和CASE里必须显式用IS NOT NULL
在COUNT()、SUM()、AVG()这类聚合函数中,NULL会被自动忽略,但你想统计“非空行数”,就得靠COUNT(col),它等价于COUNT(*)配合WHERE col IS NOT NULL。
更关键的是,在CASE或IF()里,=比较对NULL完全失效:
-
IF(age = NULL, 'missing', age)永远返回'missing'?错,它永远返回age(因为age = NULL结果是UNKNOWN,被当FALSE处理) - 正确写法是
IF(age IS NULL, 'missing', age) -
CASE WHEN status = 'active' THEN 1 WHEN status IS NULL THEN 0 ELSE 2 END——WHEN status = NULL这种写法无效
容易被忽略的一点:IS NOT NULL在HAVING子句里也完全合法,比如HAVING AVG(score) IS NOT NULL,用来排除那些因全NULL导致聚合结果为NULL的分组。


















