LIKE (Transact-SQL)
适用于:SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics Analytics Platform System (PDW) Microsoft Fabric 中的 SQL 终结点 Microsoft Fabric 中的仓库 Microsoft Fabric SQL 数据库
确定特定字符串是否与指定模式相匹配。 模式可以包含常规字符和通配符。 模式匹配过程中,常规字符必须与字符串中指定的字符完全匹配。 但是,通配符可以与字符串的任意部分相匹配。 与使用 =
和 !=
字符串比较运算符相比,使用通配符可使 LIKE
运算符更加灵活。 如果任一参数都不属于字符串数据类型,SQL Server 数据库引擎会尽量将它转换为使用字符串数据类型。
语法
SQL Server 和 Azure SQL 数据库的语法:
match_expression [ NOT ] LIKE pattern [ ESCAPE escape_character ]
Azure Synapse Analytics 和并行数据仓库的语法:
match_expression [ NOT ] LIKE pattern
ESCAPE
和 STRING_ESCAPE
在 Azure Synapse Analytics 或 Analytics Platform System (PDW) 中不受支持。
参数
match_expression
任何有效的字符数据类型的表达式。
pattern
要在 match_expression 中搜索并且可以包括下表中有效通配符的特定字符串。 pattern 的最大长度可达 8,000 字节。
如果 match_expression 数据类型的优先级高于 pattern,并且 pattern 长度大于 match_expression,则在 pattern 值隐式转换为 match_expression 类型时会出现截断错误。
通配符 | 描述 | 示例 |
---|---|---|
% |
包含零个或多个字符的任意字符串。 | WHERE title LIKE '%computer%' 将查找在书名中任意位置包含单词 computer 的所有书名。 |
_ (下划线) |
任何单个字符。 | WHERE au_fname LIKE '_ean' 将查找所有以 ean 结尾的四个字母的名字(Dean 、Sean 等)。 |
[ ] |
指定范围 [a-f] 或集合 [abcdef] 内的任何单个字符。 |
WHERE au_lname LIKE '[C-P]arsen' 将查找以 arsen 结尾并且以介于 C 与 P 之间的任何单个字符开始的作者姓氏,例如 Carsen 、Larsen 、Karsen 等。 在范围搜索中,范围包含的字符可能因排序规则的排序规则而异。 |
[^] |
不在指定范围 [^a-f] 或集合 [^abcdef] 内的任何单个字符。 |
WHERE au_lname LIKE 'de[^l]%' 将查找以 de 开头且后跟字母不是 l 的所有作者姓氏。 |
escape_character
位于通配符前的字符,用于指明将通配符解释为常规字符,而不是通配符。 escape_character 是字符表达式,无默认值,并且计算结果必须仅为一个字符。
结果类型
布尔值
结果值
如果 match_expression 与指定的 pattern 相匹配,则 LIKE
返回 TRUE。
备注
如果使用 LIKE
执行字符串比较,模式字符串中的所有字符都有意义。 有意义的字符包括任何前导或尾随空格。 如果查询中的比较要返回包含字符串 LIKE 'abc '
(abc
后跟一个空格)的所有行,则不会返回列值为 abc
(abc
后没有空格)的行。 但是可以忽略模式所要匹配的表达式中的尾随空格。 如果查询中的比较要返回包含字符串 LIKE 'abc'
(abc
后没有空格)的所有行,则返回以 abc
开始并且具有零个或多个尾随空格的所有行。
鉴于各数据类型的数据存储方式不同,如果使用包含 char 和 varchar 数据的模式进行字符串比较,可能无法传递 LIKE
比较。 下面的示例先将本地 char 变量传递给存储过程,再使用模式匹配来查找姓氏以一组指定字符开头的所有员工。
-- Uses AdventureWorks
CREATE PROCEDURE FindEmployee @EmpLName CHAR(20)
AS
SELECT @EmpLName = RTRIM(@EmpLName) + '%';
SELECT p.FirstName,
p.LastName,
a.City
FROM Person.Person p
INNER JOIN Person.Address a
ON p.BusinessEntityID = a.AddressID
WHERE p.LastName LIKE @EmpLName;
GO
EXEC FindEmployee @EmpLName = 'Barb';
GO
当名字中包含的字符数小于 20 时,char 变量 (@EmpLName
) 将包含尾随空格,这导致 FindEmployee
过程中没有行返回。 由于 LastName
列为 varchar 类型,因此没有尾随空格。 因为尾随空格是有意义的,所以此过程失败。
但以下示例会成功,因为没有向 varchar 变量中添加尾随空格。
-- Uses AdventureWorks
CREATE PROCEDURE FindEmployee @EmpLName VARCHAR(20)
AS
SELECT @EmpLName = RTRIM(@EmpLName) + '%';
SELECT p.FirstName,
p.LastName,
a.City
FROM Person.Person p
INNER JOIN Person.Address a
ON p.BusinessEntityID = a.AddressID
WHERE p.LastName LIKE @EmpLName;
GO
EXEC FindEmployee @EmpLName = 'Barb';
GO
结果集如下。
FirstName LastName City
---------- -------------------- ---------------
Angela Barbariol Snohomish
David Barber Snohomish
(2 row(s) affected)
使用 LIKE 的模式匹配
LIKE
支持 ASCII 模式匹配和 Unicode 模式匹配。 如果所有参数(match_expression、pattern 和 escape_character,如果存在)均为 ASCII 字符数据类型,则执行 ASCII 模式匹配。 如果任何一个参数为 Unicode 数据类型,则所有参数都将转换为 Unicode,并执行 Unicode 模式匹配。 如果将 Unicode 数据(nchar 或 nvarchar 数据类型)与 LIKE
结合使用,尾随空格很重要;但对于非 Unicode 数据,尾随空格并不重要。 Unicode LIKE
与 ISO 标准兼容。 ASCII LIKE
与 SQL Server 的早期版本兼容。
下面的一系列示例显示了 ASCII 与 Unicode LIKE
模式匹配所返回的行之间的差异。
-- ASCII pattern matching with char column
CREATE TABLE t (col1 CHAR(30));
INSERT INTO t
VALUES ('Robert King');
SELECT * FROM t
WHERE col1 LIKE '% King'; -- returns 1 row
-- Unicode pattern matching with nchar column
CREATE TABLE t (col1 NCHAR(30));
INSERT INTO t
VALUES ('Robert King');
SELECT * FROM t
WHERE col1 LIKE '% King'; -- no rows returned
-- Unicode pattern matching with nchar column and RTRIM
CREATE TABLE t (col1 NCHAR(30));
INSERT INTO t
VALUES ('Robert King');
SELECT * FROM t
WHERE RTRIM(col1) LIKE '% King'; -- returns 1 row
注意
LIKE
比较受排序规则影响。 有关详细信息,请参阅排序规则 (Transact-SQL)。
使用 %
通配符
如果指定了 LIKE '5%'
符号,数据库引擎将搜索后跟零个或多个任意字符的数字 5
。
例如,以下查询显示 AdventureWorks2022
数据库中的所有动态管理视图,因为它们全部以字母 dm
开始。
-- Uses AdventureWorks
SELECT Name
FROM sys.system_views
WHERE Name LIKE 'dm%';
GO
若要查看所有非动态管理视图的对象,请使用 NOT LIKE 'dm%'
。 如果共有 32 个对象,且 LIKE
找到 13 个名称与模式匹配,那么 NOT LIKE
就会找到 19 个对象与 LIKE
模式不匹配。
使用 LIKE '[^d][^m]%'
之类的模式不一定每次找到的名称都相同。 可能仅找到 14 名称(而不是 19 个),除了动态管理视图名称外,所有以 d
开始或第二个字母为 m
的名称也都将从结果中消除。 之所以出现此行为是因为,用否定通配符匹配字符串是分步骤进行评估,一次评估一个通配符。 如果在评估过程中任一环节匹配失败,它就会被消除。
将通配符作为文字使用
可以将通配符模式匹配字符作为文字字符使用。 若要将通配符作为文字字符使用,请将通配符放在方括号中。 下表显示了几个使用 LIKE
关键字和 [ ]
通配符的示例。
符号 | 含义 |
---|---|
LIKE '5[%]' |
5% |
LIKE '[_]n' |
_n |
LIKE '[a-cdf]' |
a 、b 、c 、d 或 f |
LIKE '[-acdf]' |
- 、a 、c 、d 或 f |
LIKE '[ [ ]' |
[ |
LIKE ']' |
] |
LIKE 'abc[_]d%' |
abc_d 和 abc_de |
LIKE 'abc[def]' |
abcd 、abce 和 abcf |
使用 ESCAPE 子句的模式匹配
可搜索包含一个或多个特殊通配符的字符串。 例如,customers 数据库中的 discounts 表可能存储含百分号 (%) 的折扣值。 若要搜索作为字符而不是通配符的百分号,必须提供 ESCAPE 关键字和转义符。 例如,一个样本数据库包含名为 comment 的列,该列含文本 30%。 若要搜索在 comment 列中的任何位置包含字符串 30% 的任何行,请指定 WHERE comment LIKE '%30!%%' ESCAPE '!'
之类的 WHERE 子句。 如果未指定 ESCAPE 和转义字符,数据库引擎会返回包含字符串 30!
的任何行。
如果 LIKE 模式中的转义字符后面没有字符,此模式无效,且 LIKE 返回 FALSE。 如果转义字符后面的字符不是通配符,转义字符会遭放弃,且后面的字符会被视为模式中的常规字符。 这些字符包括百分号 (%)、下划线 (_) 和左方括号 ([) 通配符(如果它们包含在双方括号 ([ ]) 中的话)。 可以在双方括号字符 ([ ]) 内使用转义字符,包括转义脱字号 (^)、连字符 (-) 或右方括号 (])。
0x0000
(char(0)) 是 Windows 排序规则中未定义的字符,无法添加到 LIKE 中。
示例
A. 使用带 %
通配符的 LIKE
以下示例在 415
表中查找区号为 PersonPhone
的所有电话号码。
-- Uses AdventureWorks
SELECT p.FirstName,
p.LastName,
ph.PhoneNumber
FROM Person.PersonPhone AS ph
INNER JOIN Person.Person AS p
ON ph.BusinessEntityID = p.BusinessEntityID
WHERE ph.PhoneNumber LIKE '415%'
ORDER BY p.LastName;
GO
结果集如下。
FirstName LastName Phone
----------------- ------------------- ------------
Ruben Alonso 415-555-124
Shelby Cook 415-555-0121
Karen Hu 415-555-0114
John Long 415-555-0147
David Long 415-555-0123
Gilbert Ma 415-555-0138
Meredith Moreno 415-555-0131
Alexandra Nelson 415-555-0174
Taylor Patterson 415-555-0170
Gabrielle Russell 415-555-0197
Dalton Simmons 415-555-0115
(11 row(s) affected)
B. 使用带 %
通配符的 NOT LIKE
以下示例在 PersonPhone
表中查找区号不是 415
的所有电话号码。
-- Uses AdventureWorks
SELECT p.FirstName,
p.LastName,
ph.PhoneNumber
FROM Person.PersonPhone AS ph
INNER JOIN Person.Person AS p
ON ph.BusinessEntityID = p.BusinessEntityID
WHERE ph.PhoneNumber NOT LIKE '415%'
AND p.FirstName = 'Gail'
ORDER BY p.LastName;
GO
结果集如下。
FirstName LastName Phone
---------------------- -------------------- -------------------
Gail Alexander 1 (11) 500 555-0120
Gail Butler 1 (11) 500 555-0191
Gail Erickson 834-555-0132
Gail Erickson 849-555-0139
Gail Griffin 450-555-0171
Gail Moore 155-555-0169
Gail Russell 334-555-0170
Gail Westover 305-555-0100
(8 row(s) affected)
°C 使用 ESCAPE 子句
以下示例使用 ESCAPE
子句和转义符在 mytbl2
表的列 c1
中查找精确字符串 10-15%
。
USE tempdb;
GO
IF EXISTS (
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'mytbl2'
)
DROP TABLE mytbl2;
GO
USE tempdb;
GO
CREATE TABLE mytbl2 (c1 SYSNAME);
GO
INSERT mytbl2
VALUES ('Discount is 10-15% off'),
('Discount is .10-.15 off');
GO
SELECT c1
FROM mytbl2
WHERE c1 LIKE '%10-15!% off%' ESCAPE '!';
GO
D. 使用 [ ]
通配符
以下示例将查找 Person
表中名字为 Cheryl
或 Sheryl
的员工。
-- Uses AdventureWorks
SELECT BusinessEntityID,
FirstName,
LastName
FROM Person.Person
WHERE FirstName LIKE '[CS]heryl';
GO
以下示例查找 Person
表中姓氏为 Zheng
或 Zhang
的员工所对应的行。
-- Uses AdventureWorks
SELECT LastName,
FirstName
FROM Person.Person
WHERE LastName LIKE 'Zh[ae]ng'
ORDER BY LastName ASC,
FirstName ASC;
GO
示例:Azure Synapse Analytics 和 Analytics Platform System (PDW)
E. 使用带 %
通配符的 LIKE
以下示例在 DimEmployee
表中查找电话号码以 612
开头的所有员工。
-- Uses AdventureWorks
SELECT FirstName,
LastName,
Phone
FROM DimEmployee
WHERE phone LIKE '612%'
ORDER BY LastName;
F. 使用带 %
通配符的 NOT LIKE
下面的示例在 DimEmployee
表中查找不以 612
开头的所有电话号码。
-- Uses AdventureWorks
SELECT FirstName,
LastName,
Phone
FROM DimEmployee
WHERE phone NOT LIKE '612%'
ORDER BY LastName;
G. 使用带 _
通配符的 LIKE
以下示例在 DimEmployee
表中查找区号以 6
开头、以 2
结尾的所有电话号码。 搜索模式的末尾包含 % 通配符,用于匹配电话列值中的所有后续字符。
-- Uses AdventureWorks
SELECT FirstName,
LastName,
Phone
FROM DimEmployee
WHERE phone LIKE '6_2%'
ORDER BY LastName;