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 数据库引擎会尽量将它转换为使用字符串数据类型。

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) 中不受支持。

参数

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;

请参阅