SQL LIKE 入门:两个通配符、四种位置、一套思维
LIKE 用于按模式匹配文本。SELECT name FROM products WHERE name LIKE '%Shirt%' 返回 Blue Cotton Shirt、Shirt Stay Clips、Shirt 三行。全部能力来自两个字符。
两个通配符:% 与 _
| 通配符 | 含义 | 示例 | 匹配 |
|---|---|---|---|
% | 任意长度的字符序列,包括零个 | 'S%' | S、Sam、Sweater |
_ | 恰好一个字符,不多不少 | 'S_m' | Sam、Sum(不匹配 Steam) |
% 的"包括零个"是最常被忽略的点:'S%' 匹配单个字母 S,因为 % 允许代表"什么都没有"。下划线不宽容,它要求必须有一个字符。
练习:'_at' 匹配什么?flat 在不在?答案:匹配 cat、hat、bat 这类"以 at 结尾的三字符值";flat 不匹配——_ 只覆盖一个字符而 flat 在 at 前有两个字符,想要两者写 '%at'。通配符可混用:'A__-%' 匹配以 A 开头、后跟恰好两个字符、再接连字符、然后任意内容的模式——适合产品代码、账号这类格式固定内容不固定的字段。
% 放哪,就是问什么
同一个通配符,四种位置四种问题:
| 写法 | 在问什么 | 匹配 "Blue Cotton Shirt"? |
|---|---|---|
LIKE 'Shirt' | 是否恰好等于 Shirt(等同 =) | 否 |
LIKE 'Blue%' | 是否以 Blue 开头 | 是 |
LIKE '%Shirt' | 是否以 Shirt 结尾 | 是 |
LIKE '%Cotton%' | 是否任意位置包含 Cotton | 是 |
没有通配符的 LIKE 只是更慢的 =:写了 LIKE 'Shirt' 就是精确匹配,应该用 =,对下一个读查询的人更清楚。从左往右把模式读成句子:'%Cotton%' 读作"任意内容,然后 Cotton,然后任意内容"。能把模式说成句子,% 就不会放错位置。
NOT LIKE:找缺失的形状
WHERE name NOT LIKE '%Shirt%' 返回没有 Shirt 的行。比看起来更有用——"哪些行不符合预期形状"是数据清洗里最高产的问题之一:没有 @ 的邮箱、缺前缀的产品码、本该是列表却混入单值的文本列。
实践建议
- 模式里含通配符字符本身(如真需要匹配
%)用 ESCAPE 子句转义,别让它被当成通配符; - LIKE 的前导通配(
'%xxx'、'%x%')无法走普通 B-tree 索引,大表上要么用前缀匹配('x%')配合索引、要么上全文检索(PostgreSQL 的pg_trgm/to_tsvector); - 用 LIKE 做"是否包含"的布尔判断时考虑
POSITION/INSTR或正则,语义更清晰; - 数据清洗场景用
NOT LIKE找异常形状,比正向匹配更高效。