能,NOT LIKE 实现模糊不匹配,但会过滤 NULL 值且需注意转义;复杂逻辑建议用正则,简单前缀/后缀排除优先用 NOT LIKE。

NOT LIKE 能直接实现“模糊不匹配”吗?
能,但要注意它只否定 LIKE 的模式匹配结果,不是对整个字段做“排除子串”的通用操作。比如 name NOT LIKE '%admin%' 确实会筛掉含 admin 的记录,但若字段为 NULL,该行**一定不会被返回**——因为 NULL NOT LIKE '...' 恒为 UNKNOWN,而 WHERE 只接受 TRUE。
常见错误:忽略 NULL 和转义字符
实际写 NOT LIKE 时,最容易漏掉两件事:
-
NULL值默认被过滤,需显式补上OR column_name IS NULL(如果业务允许保留空值) - 当模式里含
_或%字面量时,没加ESCAPE会导致误匹配。例如查不以字面量10%开头的记录,得写NOT LIKE '10\%' ESCAPE '\' - 不同数据库默认转义符不同:PostgreSQL 不设默认转义符,MySQL 默认用反斜杠,SQL Server 需手动指定
替代方案:REGEXP / RLIKE 在复杂场景更可靠
当“不匹配”逻辑变复杂(比如“不以 a/b/c 开头且不含数字”),NOT LIKE 很快力不从心。这时优先考虑正则:
- MySQL:用
NOT REGEXP,如name NOT REGEXP '^admin|root$' - PostgreSQL:用
!~操作符,如name !~ '^(admin|root)$' - 注意:正则不走索引(除非有函数索引或支持正则的专用索引),大数据量时比
NOT LIKE慢得多
性能和可读性取舍:什么时候坚持用 NOT LIKE
如果只是简单排除前缀、后缀或中间子串,NOT LIKE 更轻量、更易读、更容易被优化器利用索引(尤其是前导匹配,如 NOT LIKE 'abc%'):
- 能用
NOT LIKE 'abc%'就别写NOT REGEXP '^abc' - 避免写
NOT LIKE '%abc%'——这种通配符在前后都存在时基本无法用索引,全表扫描风险高 - 某些 ORM(如 Django ORM 的
exclude(field__contains=...))底层就翻译成NOT LIKE '%...%',要知道它背后代价

















