SQL LIKE:前缀、后缀与子串筛选

SQL LIKE 通过将字符串列与带通配符的模式比较来筛选行。% 通配符匹配零个或多个字符,_ 匹配恰好一个字符。它适合做 SQL 前缀匹配('前缀%')、后缀匹配('%后缀')和子串匹配('%关键词%')。

SQL LIKE 前缀匹配示例

输出:

输出将显示在这里...

输出:

+--------+----------------+
| name   | email          |
+--------+----------------+
| 艾丽丝 | [email protected] |
| 艾琳娜 | [email protected] |
+--------+----------------+
2 row(s)

LIKE ‘艾%’ 如何筛选行

  1. CREATE TABLEINSERTcustomers 填入四行数据。
  2. name LIKE '艾%' 只保留以 开头的名字,% 匹配后续剩余字符。
  3. name 上有普通 B-tree 索引时,像 '艾%' 这样的前缀模式可以使用索引范围扫描。

什么是 SQL LIKE 运算符?

SQL LIKE 会将字符串列与模式进行比较。除非在一侧或两侧加上 %,否则 LIKE 匹配的是整个字符串而不是子串。没有通配符时,LIKE 'text' 的行为与 = 'text' 相同。如果列值为 NULL,LIKENOT LIKE 都会计算为 unknown,该行会被 WHERE 过滤掉。

通配模式:%、_ 与 ESCAPE

%_ 覆盖了大多数筛选需求。在 SQL WHERE 通配模式里,把固定文本和 %_ 组合就能表达前缀、后缀、子串匹配:

模式含义匹配示例
'艾%' 开头艾丽丝、艾琳娜
'%org'org 结尾[email protected]
'%mail%'包含 mail[email protected]
'_ob'任意单字符 + obBob

要搜索字面量 %_,可用 ESCAPE 子句定义转义字符:

SELECT label FROM metrics
WHERE label LIKE '%100\%%' ESCAPE '\';

这里将 \ 声明为转义字符,因此 \% 匹配真实的 %,而不是把它当通配符。

SQL NOT LIKE:排除匹配行

NOT LIKE 会反转匹配条件。SQL query NOT LIKE 会返回所有不匹配该模式的行:

SELECT name FROM customers
WHERE email NOT LIKE '%corp%';

该查询会返回鲍勃和卡萝尔,也就是邮箱不包含 corp 的用户。列值为 NULL 的行会同时被 LIKE 和 NOT LIKE 排除。若要包含 NULL,需显式添加 OR column IS NULL

SQL LIKE 的常见错误

错误: 误以为 LIKE 'term' 会匹配子串。

错误写法:

WHERE name LIKE 'li'

正确写法:

WHERE name LIKE '%li%'

原因:LIKE 匹配的是整个字符串。两侧不加 % 时,模式要求与 li 完全匹配。

错误: 搜索字面量 % 时未使用 ESCAPE。

错误写法:

WHERE discount LIKE '100%'

正确写法:

WHERE discount LIKE '100\%' ESCAPE '\'

原因:不使用 ESCAPE 时,% 会作为通配符,匹配 1001000100USD 以及其他任何以 100 开头的值。

LIKE 性能:前缀模式 vs 前导通配符

在普通 B-tree 索引上,LIKE 'abc%' 可以使用索引范围扫描。以 % 开头的模式(如 '%abc''%abc%')会阻止索引定位,因此引擎通常需要扫描更多行。

对于大规模子串搜索,应使用全文检索(FTS),而不是 LIKE '%term%'

不同数据库方言的大小写敏感性

LIKE 的大小写行为会因数据库引擎而异:

数据库LIKE 默认行为
PostgreSQL区分大小写;不区分可用 ILIKE
MySQL取决于列排序规则(通常不区分)
SQLite默认对 ASCII 字母不区分大小写

在 SQLite 中,LIKE 'al%'LIKE 'Al%' 对 ASCII 字母效果相同。PRAGMA case_sensitive_like = ON 可切换为精确大小写匹配。PostgreSQL 的 ILIKE 是扩展,不属于 SQL 标准。

把列包在 LOWER() 中虽可跨方言工作,但会阻止索引使用。性能敏感场景应优先使用不区分大小写的排序规则或方言专用运算符。