
你写 SQL 时有没有遇到过这种情况:只知道用户名里“大概包含某个字”,却拿不准怎么把条件写对?SQL 模糊查询就是解决这类“不确定完整值”的查询方式,核心答案是:用 LIKE 通配符(最常用的是百分号 % 和下划线 _),就能按“包含、开头、结尾、指定长度”等规则匹配字符串。本文基于 MySQL 8.0 与标准 SQL 验证,把百分号通配符、下划线通配符、ESCAPE 转义三种写法讲透,并附一张横向对比表和踩坑清单。看完你不仅能写出正确的 SQL 模糊查询,还能在性能上少踩坑。今天这篇文章,编程狮就把这块讲透。
先看结论
| 你的需求 | 该用的写法 | 一句话示例 |
|---|---|---|
| 包含某段字符 | 百分号通配符 % | LIKE '%猫%' |
| 限定字符长度 | 下划线通配符 _ | LIKE '猫__' |
| 匹配真正的 % 或 _ | ESCAPE 转义 | LIKE '%#_%' ESCAPE '#' |
💡 小提示:九成的 SQL 模糊查询用百分号通配符就够;只有要匹配“任意单个字符”或“字面量百分号”时才轮到另外两种。
一、SQL 模糊查询到底是什么
SQL 模糊查询是相对于“精确相等(=)”的一种字符串匹配方式:它不要求值完全一样,只要符合你给的“模式”就返回行。模式由普通字符加 LIKE 通配符组成,通配符在 LIKE 语义里代表“可变的占位”。
⚠️ 注意:LIKE 是否区分大小写取决于数据库与排序规则。MySQL 默认对英文不区分大小写,PostgreSQL 默认区分;写跨库 SQL 时要心里有数。
先用一个最小可运行示例建立直觉:
-- 建一张演示表
CREATE TABLE users (
id INT PRIMARY KEY,
nickname VARCHAR(50)
);
INSERT INTO users VALUES
(1, '橘猫小传'), (2, '狸花猫日记'), (3, '布偶猫'), (4, '狗子不秃头');
-- SQL 模糊查询:找出昵称里带“猫”的所有用户
SELECT * FROM users WHERE nickname LIKE '%猫%';
上面这段做的是:在 nickname 列上做 SQL 模糊查询,百分号通配符 % 代表“猫”前后可以有任意字符。预期结果会返回 id 为 1、2、3 的三行。如果你还不熟悉基础语法,可以先过一遍 SQL 教程,把 SELECT 和 WHERE 的骨架铺平。
二、方案一:百分号通配符(%)
百分号通配符(%)匹配“任意长度(含零长度)的任意字符串”,是 SQL 模糊查询里出场率最高的一种。把 % 放在不同位置,语义完全不同:
| 写法 | 含义 | 命中示例 |
|---|---|---|
LIKE '猫%' |
以“猫”开头 | 猫之初、猫咪物语 |
LIKE '%猫' |
以“猫”结尾 | 橘猫、狸花猫 |
LIKE '%猫%' |
任意位置包含“猫” | 任意含猫的昵称 |
-- 查以“猫”开头的昵称
SELECT * FROM users WHERE nickname LIKE '猫%';
-- 查第二个字起包含“猫”的昵称(猫前恰好一个任意字符)
SELECT * FROM users WHERE nickname LIKE '_猫%';
上面两个查询分别演示了百分号通配符在开头与结尾的用法;第二句里的下划线通配符我们下一节再展开。命令后紧跟的 WHERE 条件,就是最稳的 SQL 模糊查询起步写法。

💡 小提示:想快速验证模式效果,可以打开 MySQL 速查手册 边查边试,字符串函数一节也列出了 LIKE 的常见组合。
三、方案二:下划线通配符(_)
下划线通配符()只匹配“恰好一个任意字符”,这点要和 % 区分开:% 是“任意长度”, 是“刚好一个”。当你想限定字符个数时,它比百分号通配符更精确。
-- 昵称恰好 3 个字且中间是“猫”:形如 某猫某
SELECT * FROM users WHERE nickname LIKE '_猫_';
-- 昵称第 2 个是“猫”、总长不限定
SELECT * FROM users WHERE nickname LIKE '_猫%';
第一条会命中“橘猫小”(橘_猫_小,前后各一个汉字)。执行后预期只返回这一行。下划线通配符在“按长度定位”的场景里,比百分号通配符省事得多。
⚠️ 注意:_ 只代表一个字符,不是“一个汉字”的专属。在 UTF-8 下,一个汉字就是一个字符,所以
_猫_就是“前后各一个汉字 + 中间猫”。
四、方案三:ESCAPE 转义与横向对比
前两种写法里,% 和 _ 本身是“通配符”。可万一你的数据里真的含有百分号或下划线(比如折扣字段“50% off”),LIKE '%50%%' 会把 % 当成通配符,匹配出错。这时候要用 ESCAPE 转义,给通配符“解魔法”:
-- 用 # 作为转义符,匹配字面量的 %
SELECT * FROM products WHERE name LIKE '%#%%' ESCAPE '#';
-- 匹配字面量的下划线
SELECT * FROM products WHERE code LIKE '%#_%' ESCAPE '#';
上面 ESCAPE 转义的作用是:紧跟在 # 后面的 % 或 _ 会被当作普通字符,不再具有通配含义。MySQL 还支持 REGEXP / RLIKE 做正则匹配,适合“更复杂模式”,但正则不走索引,大表要慎用。
把三种写法摆在一起对比:
| 方案 | 适用场景 | 优点 | 代价 |
|---|---|---|---|
| 百分号通配符 % | 包含/开头/结尾匹配 | 最直观、覆盖九成场景 | 前缀 % 会导致索引失效 |
| 下划线通配符 _ | 限定字符个数 | 长度精确 | 只能匹配单个字符 |
| ESCAPE 转义 | 匹配字面量 % 或 _ | 处理特殊字符 | 语义稍绕,需约定转义符 |

五、踩坑清单
把最容易卡住的三点列出来,每条给现象、原因、修复:
- 现象:LIKE '%猫%' 查询特别慢。 原因:前缀带 % 让 B+Tree 索引用不上,触发全表扫描。修复:把高频模糊查询改成“后缀索引”(MySQL 8.0 可用
REVERSE()函数建索引)或前缀匹配LIKE '猫%'。 - 现象:查不出本该命中的行。 原因:字段里混了空格或全角字符,模式对不上。修复:先用
TRIM()清洗,或REPLACE(nickname,' ','')后再比。 - 现象:想查“50%”却匹配到一堆无关行。 原因:% 被当成通配符。修复:用 ESCAPE 转义把 % 当作字面量,如上节示例。
总结
SQL 模糊查询的核心,就是用 LIKE 加通配符按“模式”匹配,而不是精确相等。优先用百分号通配符(%)解决“包含/开头/结尾”这类最常见需求;需要限定字符个数时,下划线通配符()更精确;当数据本身含有 % 或 时,用 ESCAPE 转义解除它们的通配含义。记住前缀 % 会让索引失效,大表查询要谨慎。把这张对比表存进脑子,下次写 SQL 模糊查询就不会再对着 WHERE 发呆。
要点带走:
- 百分号通配符匹配任意长度,下划线通配符只匹配单个字符;
- ESCAPE 转义用于处理字面量的 % 与 _;
- 前缀模糊(%xxx)慎用,性能上最容易翻车。
下一步可以系统补齐 SQL 基础,再练几道字符串查询题。
延伸学习
想把 SQL 基础系统补齐,可以按这个顺序来:
- 先过一遍 MySQL 教程,把 SELECT、WHERE 和字符串函数铺平;
- 遇到真实建表与查询示例,翻 MySQL 数据表结构笔记 对照着看;
- 想边学边练,编程课程 里有配套图文微课,适合巩固。
常见问题
Q:LIKE 和等号 = 有什么区别?
A:等号要求值完全相等,LIKE 按模式匹配。比如 = '猫' 只命中恰好是“猫”的行,而 SQL 模糊查询 LIKE '%猫%' 会命中所有包含“猫”的行。大部分“大概长这样”的需求都用 LIKE。
Q:为什么我的 LIKE '%关键词%' 很慢?
A:因为开头的 % 让数据库没法走索引,只能全表逐行比对。能确定前缀时就写 LIKE '关键词%',或给字段加反向索引来补救。
Q:怎么查询包含百分号 % 的数据?
A:直接用 % 会被当通配符。要用 ESCAPE 转义,例如 LIKE '%#%%' ESCAPE '#',其中 # 后的 % 表示字面量的百分号。

TRAE-AI编程



