not like查不到空值是因为null参与任何比较均返回unknown,where只保留true结果;需显式添加or col is null处理空值。

SQL中NOT LIKE为什么查不到空值?
直接用 NOT LIKE '%abc%' 会漏掉所有 NULL 字段的记录,因为 SQL 中任何与 NULL 的比较(包括 NOT LIKE)都返回 UNKNOWN,而 WHERE 只保留 TRUE 结果。
常见错误现象:明明表里有几条字段为空的记录,但 SELECT * FROM t WHERE col NOT LIKE '%x%' 就是查不出来。
- 必须显式处理
NULL:加上OR col IS NULL - 如果业务上「空」和「不匹配」要同等对待,推荐写成
WHERE col NOT LIKE '%x%' OR col IS NULL - 若想排除空值只查非空且不含目标字符的,就用
WHERE col IS NOT NULL AND col NOT LIKE '%x%'
通配符转义问题:下划线_和百分号%怎么查字面意思?
当你要查真实包含 _ 或 % 的字符串(比如查用户名为 admin%),NOT LIKE 会把它们当通配符用,导致结果错乱。
解决方法是声明一个转义字符,并在字面量中使用它:
SELECT * FROM users WHERE username NOT LIKE '%%%' ESCAPE '';
这条语句查的是「用户名不包含字面意义的 %」。
- 转义字符可以是任意单字符,常用
、!或# - MySQL 默认支持
,PostgreSQL 需显式加ESCAPE,SQL Server 同样需要 - 别忘了对转义字符本身做双重转义(如写
'%\%%'当转义符是且字符串来自程序拼接)
区分大小写影响:NOT LIKE 在不同数据库是否敏感?
答案取决于字段的排序规则(collation),不是 NOT LIKE 本身决定的。例如:
- MySQL 中
utf8mb4_general_ci是不区分大小写的,'ABC' NOT LIKE '%abc%'返回FALSE - PostgreSQL 默认区分大小写,
'ABC' NOT LIKE '%abc%'返回TRUE - SQL Server 若列用
_CS(case-sensitive)排序规则,行为同 PostgreSQL
需要强制不区分时,可用函数统一转换:
SELECT * FROM t WHERE UPPER(col) NOT LIKE UPPER('%abc%');
但注意:这会让索引失效,大数据量时慎用。
性能隐患:NOT LIKE很难走索引
NOT LIKE 几乎无法利用 B-tree 索引,尤其当模式以通配符开头(如 NOT LIKE '%x%')时,数据库只能全表扫描。
-
col NOT LIKE 'abc%'有可能用上索引前缀(取决于优化器和统计信息),但不保证 - 真正能稳定走索引的是
col LIKE 'abc%'这类前缀匹配 - 如果高频查询「不含某子串」,考虑增加计算列 + 索引,或改用全文检索(如 PostgreSQL 的
to_tsvector)
实际执行前务必看 EXPLAIN,别被 NOT LIKE 的语法迷惑——它看起来像条件过滤,实则常是性能黑洞。











