假设您有一张 employees 表,想要找到所有以 “A” 开头的名字:
employees | |||||
emp_no | birth_date | first_name | last_name | gender | hire_date |
10001 | 1953-09-02T00:00:00.000Z | Georgi | Facello | M | 1986-06-26T00:00:00.000Z |
10002 | 1964-06-02T00:00:00.000Z | Bezalel | Simmel | F | 1985-11-21T00:00:00.000Z |
10003 | 1959-12-03T00:00:00.000Z | Parto | Bamford | M | 1986-08-28T00:00:00.000Z |
您当然可以手动翻阅整张表,但既然有 LIKE 运算符,何必如此呢?
SELECT DISTINCT
first_name
FROM employees
WHERE first_name LIKE 'A%'关键在于子句 `WHERE first_name LIKE ‘A%’`,意思是“查找所有以 "A" 开头,后接任意数量字符的 first_name”。这里的 A% 就是用于匹配的模式。
% 并不是与 LIKE 搭配使用的唯一通配符,您也可以使用下划线 _:
`%`匹配任意数量的字符。_匹配任意单个字符。
语法很容易记忆,就是:
column_name LIKE pattern您可以用 LIKE 实现多种模式匹配。方法如下:
SQL LIKE 入门示例
下面列出了一些使用 LIKE 语句的实用示例,以及我们示例数据集对应的结果。
1. 使用 LIKE 进行精确字符串匹配
如果您要进行精确字符串匹配,可在不使用 “%” 或 “_” 的情况下使用 LIKE
SELECT
first_name, last_name
FROM employees
WHERE first_name LIKE 'Barry' -- the same as WHERE first_name = ‘Barry’2. 使用 “%” 匹配任意数量的字符
“%” 可用于匹配任意(甚至为零个)数量的字符——数字、字母或符号。
假设您想找出名字以 “Adam” 开头的所有员工;可以使用模式 “Adam%”
SELECT DISTINCT
first_name
FROM employees
WHERE first_name LIKE 'Adam%'要查找以 "z" 结尾的名字,使用模式 “%z”。同一个模式中也可以使用多个 “%”。例如,想找出包含 "z" 的名字,可用 “%z%”。
3. 使用 “_” 匹配一个(且仅一个)字符
就像“刽子手”(Hangman)游戏一样,下划线 _ 只能占一个字符。
Le_n 可以有多少种拼法?该模式会匹配从 "Lexn"、"LeAn"、"Le3n" 到 "Le-n" 的任意形式。
SELECT DISTINCT
first_name
FROM employees
WHERE first_name LIKE 'Le_n'有哪些名字只有三个字符?我们可以用三个连续的下划线 ___ 作为模式来找出。
SELECT DISTINCT
first_name
FROM employees
WHERE first_name LIKE '___'4. 同时使用 “%” 和 “_” 匹配任意模式
当然,您也可以将 “%” 和 “_” 组合,构造更有意思的模式。
SELECT DISTINCT
first_name
FROM employees
WHERE first_name LIKE '%ann_'模式 “%ann_” 匹配以任意数量字符开头、以 "ann" 加一个字符结尾的字符串。
5. 使用 NOT 查找不匹配某模式的字符串
如果您想找出不满足某个条件的所有行,可以使用 NOT LIKE 运算符。比如,要查找除 "Staff" 之外的所有职称,我们可以使用如下语法
`WHERE title NOT LIKE ‘Staff’`这与以下语法完全等价:
WHERE title != 'Staff'SELECT DISTINCT
title
FROM titles
WHERE title NOT LIKE 'Staff'当然,您也可以将 NOT LIKE 用于我们前面介绍的任意模式。
SELECT DISTINCT
title
FROM titles
WHERE title NOT LIKE '%engineer'6. 将 LOWER(或 UPPER)与 LIKE 搭配用于不区分大小写的匹配
如果需要进行模式匹配,但不确定字符串是以小写、大写还是混合形式存储,可以使用以下语法。
LOWER(column_name) LIKE patternLOWER() 函数会将所有字符串转为小写,不论其原本是大写、小写或混合大小写。
使用该语法时,请确保将模式全部写成小写!否则,可能得不到任何匹配结果。
您也可以在上述语法中用 UPPER 替换 LOWER。同时务必将模式写成大写。
`UPPER(column_name) LIKE PATTERN`例如,若要查找员工名字可能为 "Joanne"、"JoAnne"、"Joanna" 或 "JoAnna",可尝试以下任一方式:
SELECT DISTINCT
first_name
FROM employees
WHERE LOWER(first_name) LIKE 'joann_'SELECT DISTINCT
first_name
FROM employees
WHERE UPPER(first_name) LIKE 'JOANN_'7. 使用 OR/AND 让 LIKE 同时匹配多个值
您也可以在 LIKE 语法中组合多个条件。
例如,使用 OR 条件来查找满足多个 LIKE 模式中至少一个的结果。
SELECT DISTINCT
first_name
FROM employees
WHERE
first_name LIKE 'Ad_l' OR
first_name LIKE 'Ad_m'另一方面,若要查找同时满足多个 LIKE 条件的字符串,请使用 AND 关键字。
SELECT DISTINCT
first_name
FROM employees
WHERE
first_name LIKE '%am%' AND
first_name LIKE '%me%'只要列的数据类型是可变长度字符(varchar),就可以将 LIKE 语法应用到多列上。基于此,我们可以找出姓名首字母都是 "Z. Z." 的员工。
SELECT DISTINCT
first_name, last_name
FROM employees
WHERE
first_name LIKE 'Z%' AND
last_name LIKE 'Z%'8. 在 SELECT 的 CASE WHEN 子句中使用 LIKE
到目前为止,我们主要关注在WHERE 子句中将 LIKE 作为选择记录的条件。我们也可以在 SELECT 子句中使用 LIKE。例如,能否统计数据库中名为 "Adam" 的员工有多少?
SELECT
COUNT(CASE WHEN first_name LIKE 'Adam' THEN 1 END) num_employees_adam
FROM employees另一方面,首字母为 "A.Z." 的员工有多少?
SELECT
COUNT(CASE WHEN first_name LIKE 'A%' AND last_name LIKE 'Z%' THEN 1 END) num_employees
FROM employeesSQL LIKE 的常用模式
下面对我们讨论过的模式做一个速查总结:
| 模式 | 描述 | 示例用法 |
|---|---|---|
| A% | 匹配以 "A" 开头的字符串 | 查找以 "A" 开头的名字 |
| %z% | 匹配包含 "z" 的字符串 | 查找包含 "z" 的名字 |
| Le_n | 匹配类似 "Len"、"Leon" 等字符串 | 查找仅一处字符变化的名字 |
| %ann_ | 匹配以 "ann" 加一个字符结尾的字符串 | 查找如 "Joann"、"Joanna" 的名字 |
SQL LIKE 的进阶示例
LIKE 在不同 SQL 方言(如 PostgreSQL、MySQL、Redshift 等)中大体相同。但有些方言提供了值得一提的变体。
1. ILIKE 运算符
在 Redshift 和PostgreSQL 中可用,ILIKE 是大小写不敏感版本的 LIKE。因此,以下写法等价。
SELECT
datacamp ILIKE ‘datacamp’, -- returns TRUE
DATACAMP ILIKE ‘datacamp’, -- returns TRUE
Datacamp ILIKE ‘datacamp’, -- returns TRUE
datacamp ILIKE ‘DataCamp’, -- returns TRUE2. 使用方括号 [] 和 [^] 作为通配符
T-SQL 或 SQL Server 的用户有额外的通配符可进行更复杂的模式匹配。
方括号语法 [] 匹配范围或集合内的任意特定字符。例如,下面这些都会返回 TRUE。
SELECT
‘Carson’ LIKE ‘[C-K]arson’, -- returns TRUE because C is in the range C-K
‘Karson’ LIKE ‘[C-K]arson’, -- returns TRUE because K is in range
‘Larson’ LIKE ‘[CKL]arson’, -- returns TRUE because L is in the set [CKL]
‘Parson’ LIKE ‘[C-K]arson’ -- returns FALSE because P is out of range插入在方括号内的尖号 [^] 通配符,匹配不在指定范围或集合内的任意单个字符。您能看出下面结果的原因吗?
SELECT
‘Carson’ LIKE ‘[^C-K]arson’ -- returns FALSE
‘Parson’ LIKE ‘[^C-K]arson’ -- returns TRUE在此,由于 "C" 属于 [C-K] 范围,因此字符 ‘C’ 不会匹配 [^C-K]。于是,"Carson" 不会匹配 [^C-K]arson,而 "Parson" 会。
3. RLIKE 运算符
在 MySQL 中可用,RLIKE 运算符能够识别模式中的正则表达式(RegEx)。正则是进行高级模式匹配的强大而灵活的工具。
若您的 SQL 方言支持 RLIKE,了解一些正则基础非常有用。您可以通过我们的Python 正则表达式课程进一步学习。
SELECT DISTINCT
first_name
FROM employees
WHERE first_name RLIKE 'Susann[a-e]'4. “~~” 运算符
在 PostgreSQL 中,“~~” 与 LIKE 完全同义。同时还存在与 ILIKE、NOT LIKE、NOT ILIKE 等价的写法。
运算符 | 等价于 |
|
|
|
|
|
|
|
|
故障排查:使用 LIKE 的常见错误与陷阱
以下是使用 LIKE 时可能遇到的一些常见错误,以及相应的修正方法:
- 无结果返回:检查大小写敏感性。在某些 SQL 方言中,
LIKE默认区分大小写。可使用LOWER()或(若支持)ILIKE进行不区分大小写的匹配。 - 通配符导致的意外结果:确保正确使用
%和_。%匹配任意数量字符,而_仅匹配一个字符,放置不当会带来意外匹配。 - 性能问题:若查询缓慢,留意模式中的前导
%(如%pattern),它会禁用索引使用。若可能,改写为以特定字符串起始的模式。性能详见下节。 - SQL 注入错误:若查询中使用了用户输入,请确保正确参数化,避免SQL 注入风险。
- 模式中的特殊字符:若需按字面匹配搜索字符串中的
%和_等通配符,必须进行转义。使用ESCAPE在查询中定义转义字符。
WHERE column_name LIKE '50\% OFF' ESCAPE '\'使用 LIKE 运算符的性能考量
LIKE 运算符非常实用,但在大型数据集上可能影响查询性能。以下是优化建议:
- 索引:当模式以常量字符串开头(如
Adam%)时,数据库可利用索引,LIKE的性能最佳。然而,像%Adam或%Adam%这样的模式需要全表扫描,对于大表会很慢。 - 避免前导通配符:以
%起始的模式(如%pattern)会禁用索引使用,数据库不得不检查每条记录。 - 排序规则与大小写不敏感匹配:对列使用
LOWER()或UPPER()实现不区分大小写的搜索,也可能导致无法使用索引。更好的做法是将数据库排序规则设置为支持不区分大小写的比较。 - 替代方案:对于大型数据集,执行复杂或高频的字符串匹配时,考虑使用全文搜索或数据库特有的搜索功能,如 PostgreSQL 的
GIN索引或 MySQL 的FULLTEXT索引。 - 提高选择性:通过添加其他过滤条件(如日期范围或数值列)缩小查询范围,减少
LIKE需处理的数据量。
LIKE 与全文搜索
MySQL、PostgreSQL 和 SQL Server 等数据库提供全文搜索。虽然 LIKE 适合直接的模式匹配,但全文搜索为更高级的文本查询而生。两者对比如下:
| 特性 | LIKE | 全文搜索 |
|---|---|---|
| 语法 | WHERE col LIKE '%term%' | MATCH(col) AGAINST('term') |
| 通配符 | %、_ | 布尔运算符、自然语言 |
| 索引支持 | 仅支持前缀模式(如 term%) | 专用全文索引(GIN、FULLTEXT) |
| 大表性能 | 前导 % 时较慢 | 针对大文本列优化 |
| 相关性排序 | 无 | 有 |
| 语言学特性 | 无 | 词干提取、停用词、同义词 |
| 最佳适用 | 精确模式,中小规模数据集 | 关键词搜索,大型文本列 |
若您需要超出模式匹配的更高级字符串操作,请参阅SQL CONTAINS 教程。
自信使用 SQL LIKE
掌握 SQL 函数是数据科学成功的关键,SQL 的 LIKE 命令也不例外。熟练掌握 SQL 将显著加速您的分析进展,请务必深入学习!
想获得更多 SQL 资源,请查看以下内容:
FAQs
LIKE 运算符可以用于数值数据类型吗?
不可以,LIKE 运算符专门用于对 CHAR、VARCHAR 和 TEXT 等字符串数据类型进行模式匹配。对于数值数据类型,通常使用 =、<、> 等比较运算符。
LIKE 的性能相较于其他 SQL 运算符如何?
与其他 SQL 运算符相比,LIKE 在某些情况下效率更低,尤其是以 % 开头的模式,因为这需要全表扫描。在这种情况下无法有效利用索引,对大型数据集的查询可能变慢。
在 SQL 中使用 LIKE 是否存在安全隐患?
虽然 LIKE 本身并非不安全,但在 SQL 查询中直接使用用户输入会导致 SQL 注入攻击。请始终清理输入,并考虑使用参数化查询来降低风险。
在不支持 ILIKE 的 SQL 方言中,如何处理大小写敏感的搜索?
在不支持 ILIKE 的 SQL 方言中,您可以使用 LOWER(column_name) LIKE LOWER(pattern) 或 UPPER(column_name) LIKE UPPER(pattern) 来进行不区分大小写的搜索。
LIKE 能用于非 ASCII 字符吗?
可以,LIKE 可用于非 ASCII 字符,只要数据库编码支持这些字符即可。这包括常用的 UTF-8,能够支持广泛的字符集。
如何修改 LIKE 查询以搜索字面量通配符字符(例如 % 或 _)?
若要搜索字面量的 % 或 _,需要使用转义字符。例如,在 SQL Server 中,您可以使用 LIKE 'A[%]%' ESCAPE '%' 来搜索包含字面量 % 的字符串。
能否将 LIKE 与其他 SQL 函数结合以提升搜索能力?
可以,将 LIKE 与 CONCAT 或 SUBSTRING 等函数结合使用,可帮助细化搜索模式。例如,使用 CONCAT 可以基于其他列值动态构建模式。
如何将 LIKE 与 JOIN 操作结合使用?
LIKE 可用于 JOIN 条件中,用于匹配不同表中列之间的模式。例如,ON table1.col1 LIKE table2.col2 || '%' 可用于在 table1.col1 以 table2.col2 开头时将表进行连接。
在进行复杂模式匹配时,有哪些可以替代 LIKE 的方法?
对于更复杂的模式,支持正则表达式的 SQL 方言(如 MySQL 的 RLIKE 或 PostgreSQL 的 SIMILAR TO)可作为替代。它们为高级模式匹配提供了更丰富的语法。
LIKE 如何处理列中的 null 值?
当列包含空值(null)时,LIKE 不会匹配这些记录,因为 null 不等于任何字符串或模式。若要包含 null,请添加类似 OR column IS NULL 的条件。
不论您喜不喜欢,
LIKE运算符都是 SQL 中不可或缺的一部分。它让数据科学家和数据工程师能够基于特定的字符串匹配来筛选数据。在本教程中,我将从基础到进阶,带您掌握使用LIKE进行模式匹配的方法。要点速览
LIKE运算符使用两个通配符进行模式匹配:%(任意数量的字符)和_(恰好一个字符)LIKE与NOT、LOWER()/UPPER()、OR/AND以及CASE WHEN组合,实现灵活过滤ILIKE(PostgreSQL/Redshift),或对列套用LOWER()%通配符(如%pattern)会禁用索引使用——在大型数据集上请考虑全文搜索[]和[^]指定字符范围;MySQL 支持基于正则的RLIKE用于模式匹配的 SQL LIKE 运算符
注意:若您想亲自运行本教程中的所有示例代码,可创建一个免费的 DataLab 工作簿,其中已安装 SQL 并包含带示例数据的数据库。