首页 / SQLite 入门教程 / 模糊匹配 LIKE 与 GLOB

SQLite 入门教程

模糊匹配 LIKE 与 GLOB

本教程共 50 篇 · 第 23 篇 · 更新于 2026-07-31

sqliteLIKEGLOB模糊匹配通配符

23. 模糊匹配 LIKE 与 GLOB

本节目标:学完本章你能用 LIKEGLOB 写出带通配符的模糊查询,并清楚知道两套通配符怎么写、什么时候大小写敏感、两者该选哪一个。

为什么需要模糊匹配

前面我们在 WHERE 里做条件过滤,大多是用 = 做”完全相等”的判断,比如 WHERE name = 'Alice'。但真实场景里,你常常并不知道完整的值,只知道”大概长什么样”:

  • 想找出所有名字里带”张”字的人;
  • 想找出邮箱域名是某个后缀的账号;
  • 想找出文件名以 .pdf 结尾的记录;
  • 想找出车牌号第二位是某个字母的数据。

这种”按模式(pattern)去匹配,而不是按完整值去相等”的需求,就是模糊匹配,英文叫 pattern matching。SQLite 提供了两个做模糊匹配的运算符:LIKEGLOB。它们都返回一个布尔结果(匹配成功为 1,失败为 0),通常放在 WHERE 子句里当过滤条件用。

Note

重点提示:LIKEGLOB 比较的是文本users 表的 nameemail 都是 TEXT 列,最适合用来演示;即使拿数字列(如 age)去 LIKE,SQLite 也会先把数字转成文本再比较,这属于动态类型带来的”灵活”,但结果以文本形态为准。

LIKE:最常用、对人最友好的模糊匹配

LIKE 只认识两个通配符:

  • %(百分号):代表”任意长度”的任意字符,包括零个字符。它相当于”随便多少字都行”。
  • _(下划线):代表”恰好一个”任意字符。它相当于”这里必须占一个位置,但什么字都行”。

注意 SQLite 是动态类型的,列上写的 TEXT 只是类型亲和性(Type Affinity)的建议,实际存储类由值决定;不过 LIKE/GLOB 的匹配行为只看文本表示,所以理解成”在字符串上套模式”就够了。

下面是一些典型写法,假设我们用全局统一的 users 表:

sqlite> SELECT name FROM users WHERE name LIKE '张%';
sqlite> SELECT name FROM users WHERE name LIKE '%伟';
sqlite> SELECT name FROM users WHERE name LIKE '%小%';
sqlite> SELECT email FROM users WHERE email LIKE '%@gmail.com';

含义分别是:以”张”开头、以”伟”结尾、中间含”小”、邮箱以 @gmail.com 结尾。

再看 _ 的用法。假设想找”姓一个字、名是两个字、总共三个字”的名字:

sqlite> SELECT name FROM users WHERE name LIKE '__%' AND length(name) = 3;

这里 % 吃掉后面任意字符,_ 精确占一个位置。但要数清下划线个数容易出错,所以”长度固定为 N”的需求更推荐配合 length() 函数一起写,可读性更好。

LIKE 的大小写问题

LIKE 默认对 ASCII 英文字母大小写不敏感的,也就是说 WHERE name LIKE 'alice' 能匹配到 AliceALICEalice。这是因为 LIKE 默认使用 NOCASE 这种校对规则(Collation)来比较。但要特别注意:这种不敏感只覆盖 A–Z/a–z 这 26 个英文字母;对于中文、带声调的字母、或其他 Unicode 字符,LIKE 不一定不敏感,结果取决于数据库使用的校对规则。所以不要依赖 LIKE 去做”全语言大小写不敏感”,它只是英文友好。

想匹配真正的 % 或 _ 怎么办:ESCAPE

因为 %_ 被当成通配符了,如果你真的想搜”包含下划线”的字符串(比如字段名 col_1),就得用 ESCAPE 子句声明一个”转义符”:

sqlite> SELECT * FROM users WHERE name LIKE 'col|_1' ESCAPE '|';

这里 | 被声明为转义符,|_ 中的 _ 就被当成普通下划线,而不是”任意单字符”通配符。这是 LIKE 才有的能力,GLOB 没有转义机制。

GLOB:更严格、类 Unix 的大小写敏感匹配

GLOB 的写法借鉴了 Unix/Linux 的”文件名通配”(glob),通配符是另一套:

  • *(星号):匹配任意长度任意字符,等价于 LIKE%
  • ?(问号):匹配恰好一个任意字符,等价于 LIKE_
  • [...](方括号):匹配方括号里列出的”某一个”字符。例如 [abc] 匹配 a、b、c 中的任意一个;[a-z] 匹配 a 到 z 的任意一个小写字母;[0-9] 匹配任意数字。
  • [^...](^ 开头):匹配”不在”方括号列表里的任意一个字符。例如 [^0-9] 匹配任意非数字字符。

一个关键差异:GLOB 永远是大小写敏感的'Man*' 不会匹配 man*

sqlite> SELECT name FROM users WHERE name GLOB '张*';
sqlite> SELECT name FROM users WHERE name GLOB '*伟';
sqlite> SELECT name FROM users WHERE name GLOB '[A-Z]*';
sqlite> SELECT email FROM users WHERE email GLOB '*[0-9]*@*';

最后一条表示”邮箱里 @ 之前的部分含有数字”。[...]GLOB 的强项,用来做”字符集合 / 区间”匹配非常方便,而 LIKE 本身并不支持方括号语法(见下方常见坑)。

Tip

实用技巧:什么时候选 GLOB?当你需要大小写敏感或者需要方括号字符集(比如”首字母必须是大写""不能含数字”)时,用 GLOB。当你只是想做普通、对英文大小写不敏感的搜索(比如搜用户名、搜关键词),用 LIKE 更顺手,也更符合大多数人的直觉。

LIKE 与 GLOB 的区别对比

维度LIKEGLOB
多字符通配符%*
单字符通配符_?
字符集合 [abc]/[a-z]不支持支持
排除集合 [^...]不支持支持
大小写敏感对 ASCII 英文不敏感永远敏感
转义字符(ESCAPE)支持不支持
风格来源SQL 标准通用Unix glob 风格

一句话记忆:LIKE%_GLOB*?GLOB 多了一套方括号、且区分大小写。

性能与适用场景提醒

模糊匹配虽然好用,但有个代价:当模式以通配符开头(如 LIKE '%伟'GLOB '*伟')时,SQLite 往往无法利用索引,只能逐行扫描整张表去比对。数据量小无所谓,数据量大时会明显变慢。如果业务上频繁要”后缀匹配”,可以考虑冗余存储一份反转后的字符串、或用专门的 FTS5 全文检索(本教程后续章节会讲)。

Warning

常见坑:网上有些教程(如部分 runoob 内容)会写出 LIKE '[AB]%' 这种带方括号的例句,那是 MySQL / SQL Server 的写法,在 SQLite 里并不成立。SQLite 的 LIKE 只认 %_ 两个通配符,方括号 [...]GLOB 的专属语法。想在 SQLite 里做”首字母是 A 或 B”的匹配,请用 GLOB '[AB]*',或者拆成 LIKE 'A%' OR LIKE 'B%'。照搬错误写法会让你查不到本该查到的数据。

Warning

常见坑:不要把”大小写不敏感”想当然地套到所有语言上。LIKE 只对 ASCII 英文字母默认不敏感;对中文或特殊字符是否不敏感,取决于表的校对规则(Collation)。需要严格区分大小写时,直接用 GLOB 更稳妥,不要赌 LIKE 的表现。

类比小结

LIKEGLOB 想成两种”模糊搜人”的方式:

  • LIKE 像是你跟前台说”帮我找姓张的、名字里带个伟字的”,前台对英文大小写比较宽容,你说 alice 他也把 Alice 叫来;
  • GLOB 像是你拿着一份严格的门禁规则,“首字母必须大写、不能含数字”,一字之差都不行,而且区分大小写毫不含糊,还支持”字符白名单/黑名单”(方括号)。

记住通配符的对应关系(%*_?)、记住 GLOB 才支持方括号且永远大小写敏感、记住 LIKE 可用 ESCAPE 转义,模糊查询这一关就算过了。