%匹配零个或多个任意字符,_仅匹配一个且仅一个任意字符;前者为可变长贪婪匹配,后者为严格定长匹配,语义不可互换,如查三字姓名中第二字为“明”须用'_明_'而非'%明%'。

百分号 % 匹配零个或多个任意字符;下划线 _ 只匹配一个且仅一个任意字符 —— 这是语义层面的根本区别,不是写法或习惯问题,而是 SQL 标准强制定义的行为。
为什么 % 和 _ 不能互相替代
它们的“匹配长度”不可协商:% 是贪婪、可变长的,_ 是严格定长的。比如想查“第二个字是‘明’的三字姓名”,用 '_明_' 正确,用 '%明%' 会把“张明亮”“李明”“王小明”全捞出来,完全失控。
-
%出现在开头('%abc')表示结尾匹配,“abc”必须在末尾 -
_出现在开头('_abc')表示“第1位任意,第2–4位必须是 abc”,总共至少4位 - 组合使用时注意顺序:要查“以 a 开头、第3位是 b 的5位字符串”,得写
'a_b__',而不是'a%b%'—— 后者长度和位置都不受控
LIKE 中的 % 和 _ 在不同数据库里行为一致吗
核心行为(% = 多字符、_ = 单字符)在 MySQL、PostgreSQL、SQL Server、Oracle 中完全一致;但扩展功能差异大:
- 方括号
[abc]和取反[^abc]仅 SQL Server 原生支持,MySQL 和 PostgreSQL 需用正则函数(如REGEXP或~)替代 - 如果你在 PostgreSQL 里写了
WHERE name LIKE '[A-C]%',会直接报错,不是不生效,是语法不识别 - 所有主流数据库都支持
ESCAPE子句来转义自身,比如查真实含下划线的字段值,必须写LIKE '%\_%' ESCAPE '\',否则_被当通配符解析
实际写 LIKE 条件时最容易踩的坑
不是记不住规则,而是忽略上下文约束导致逻辑错误:
- 忘记
NULL值永远不匹配LIKE:如果name列有NULL,WHERE name LIKE '%a%'不会返回这些行,需显式加OR name IS NULL - 索引失效风险:以
%开头的模式(如'%abc')几乎无法走 B-tree 索引,而'abc%'可以 —— 性能差十倍以上很常见 -
_容易误数位数:写'张__'查两字姓名,但如果数据里有全角空格或不可见字符,实际长度可能超 3,结果漏查 —— 建议配合LENGTH(name) = 2双重校验 - 大小写敏感性取决于列排序规则(collation),不是
LIKE本身:MySQL 默认不区分,SQL Server 默认区分,别假设“测试库跑过就一定线上 OK”
真正难的从来不是记住 % 和 _ 各代表什么,而是判断当前业务场景中,该用哪个、能不能用、用了会不会拖慢查询、有没有被 NULL 或编码细节偷偷绕过去 —— 这些才是上线前必须验证的点。

















