LIKE (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsAnalytics Platform System (PDW)Microsoft Fabric 中的 SQL 分析终结点Microsoft Fabric 中的仓库

确定特定字符串是否与指定模式相匹配。 模式可以包含常规字符和通配符。 模式匹配过程中,常规字符必须与字符串中指定的字符完全匹配。 但是,通配符可以与字符串的任意部分相匹配。 与使用 =!= 字符串比较运算符相比,使用通配符可使 LIKE 运算符更加灵活。 如果任一参数都不属于字符串数据类型,SQL Server 数据库引擎会尽量将它转换为使用字符串数据类型。

Transact-SQL 语法约定

语法

SQL Server 和 Azure SQL 数据库的语法:

match_expression [ NOT ] LIKE pattern [ ESCAPE escape_character ]

Azure Synapse Analytics 和并行数据仓库的语法:

match_expression [ NOT ] LIKE pattern

ESCAPESTRING_ESCAPE 在 Azure Synapse Analytics 或 Analytics Platform System (PDW) 中不受支持。

注意

若要查看 SQL Server 2014 (12.x) 及更早版本的 Transact-SQL 语法,请参阅早期版本文档

参数

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 结尾的四个字母的名字(DeanSean 等)。
[ ] 指定范围 [a-f] 或集合 [abcdef] 内的任何单个字符。 WHERE au_lname LIKE '[C-P]arsen' 将查找以 arsen 结尾并且以介于 CP 之间的任何单个字符开始的作者姓氏,例如 CarsenLarsenKarsen 等。 在范围搜索中,范围包含的字符可能因排序规则的排序规则而异。
[^] 不在指定范围 [^a-f] 或集合 [^abcdef] 内的任何单个字符。 WHERE au_lname LIKE 'de[^l]%' 将查找以 de 开头且后跟字母不是 l 的所有作者姓氏。

escape_character

位于通配符前的字符,用于指明将通配符解释为常规字符,而不是通配符。 escape_character 是字符表达式,无默认值,并且计算结果必须仅为一个字符

结果类型

布尔值

结果值

如果 match_expression 与指定的 pattern 相匹配,则 LIKE 返回 TRUE。

备注

如果使用 LIKE 执行字符串比较,模式字符串中的所有字符都有意义。 有意义的字符包括任何前导或尾随空格。 如果查询中的比较要返回包含字符串 LIKE 'abc 'abc 后跟一个空格)的所有行,则不会返回列值为 abcabc 后没有空格)的行。 但是可以忽略模式所要匹配的表达式中的尾随空格。 如果查询中的比较要返回包含字符串 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]' abcdf
LIKE '[-acdf]' -acdf
LIKE '[ [ ]' [
LIKE ']' ]
LIKE 'abc[_]d%' abc_dabc_de
LIKE 'abc[def]' abcdabceabcf

使用 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 表中名字为 CherylSheryl 的员工。

-- Uses AdventureWorks

SELECT BusinessEntityID,
    FirstName,
    LastName
FROM Person.Person
WHERE FirstName LIKE '[CS]heryl';
GO

以下示例查找 Person 表中姓氏为 ZhengZhang 的员工所对应的行。

-- 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;

请参阅