必须使用ESCAPE子句显式转义:如WHERE name LIKE '%_%' ESCAPE '',将反斜杠声明为转义符后,_%才表示字面意义的下划线;同理,!%在ESCAPE '!'下表示字面百分号。

LIKE 查询中下划线和百分号被当成通配符怎么办
直接用 LIKE '%_%' 或 LIKE '%%' 会匹配任意单个字符或任意长度字符串,根本查不到字面意义的 _ 或 %。因为 SQL 标准里这两个字符在 LIKE 中默认就是通配符: _ 匹配一个任意字符,% 匹配零个或多个任意字符。
用 ESCAPE 显式声明转义字符
最通用、跨数据库(MySQL、PostgreSQL、SQL Server、Oracle)都支持的方式是加 ESCAPE 子句。选一个不常出现在目标字段里的字符(比如 、! 或 |),声明它为转义符,然后在要匹配的 _ 或 % 前加上它:
SELECT * FROM users WHERE username LIKE '%_%' ESCAPE '';
SELECT * FROM logs WHERE message LIKE '%!%%' ESCAPE '!';
-
ESCAPE ''表示反斜杠是转义符,所以_就代表字面的下划线 -
ESCAPE '!'表示叹号是转义符,所以!%就代表字面的百分号 - 如果字段本身可能含转义符(比如用户名里真有
),得先双写它:'%\\_%'(四个反斜杠 → 数据库解析成两个 → 实际匹配一个反斜杠加一个下划线)
不同数据库的等效写法差异
虽然 ESCAPE 是标准写法,但有些数据库提供更简洁的替代方案,注意兼容性:
- PostgreSQL 支持
ESCAPE,也允许用~操作符配合正则:WHERE col ~ '_'(但这时_是字面量,不是通配符) - MySQL 8.0+ 可用
REGEXP:WHERE col REGEXP '_'——正则里的_默认就是字面量,无需额外转义 - SQL Server 用方括号也能绕过:
WHERE col LIKE '%[_]%'匹配含下划线的值;WHERE col LIKE '%[%]%'匹配含百分号的值(方括号内字符不参与通配) - SQLite 不支持
ESCAPE的老版本(3.16 以前)只能靠INSTR()或REPLACE()曲线救国,例如:WHERE INSTR(col, '_') > 0
容易忽略的边界情况
即使加了 ESCAPE,仍可能漏掉结果或误匹配:
- 字段值为空(
NULL)时,LIKE表达式一律返回UNKNOWN,不会进结果集,记得加OR col IS NULL(如果业务需要) - 大小写敏感性:某些数据库(如 MySQL 默认不区分,PostgreSQL 默认区分),
LIKE匹配受排序规则影响,必要时显式用ILIKE(PostgreSQL)或COLLATE utf8mb4_general_ci - 前导/尾随空格:如果字段是
CHAR类型,可能带空格,LIKE 'a_%'未必能匹配'a_ ',建议先RTRIM()或改用POSITION('_' IN col) > 0
真正麻烦的不是语法,而是确认你的数据里到底有没有这些字符、它们是否被其他逻辑(比如 ORM 自动转义、前端输入过滤)提前处理过。查不到时,先 SELECT HEX(col) 或 SELECT DUMP(col) 看原始字节更靠谱。

















