12.7.1 字符串比较函数和运算符

table12.12 字符串比较函数和运算符

NameDescription
LIKE简单模式匹配
NOT LIKE否定简单模式匹配
STRCMP()比较两个字符串

如果给字符串函数一个二进制字符串作为参数,则结果字符串也是二进制字符串。转换为字符串的数字被视为二进制字符串。这仅影响比较。

通常,如果字符串比较中的任何 table 达式区分大小写,则以区分大小写的方式执行比较。

expr LIKE pat [ESCAPE'escape_char']

使用 SQL 模式进行模式匹配。返回1(TRUE)或0(FALSE)。如果* expr pat *为NULL,则结果为NULL

该模式不必是 Literals 字符串。例如,可以将其指定为字符串 table 达式或 table 列。

根据 SQL 标准,LIKE按每个字符执行匹配,因此它产生的结果不同于=比较运算符:

mysql> SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
+-----------------------------------------+
| 'ä' LIKE 'ae' COLLATE latin1_german2_ci |
+-----------------------------------------+
|                                       0 |
+-----------------------------------------+
mysql> SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
+--------------------------------------+
| 'ä' = 'ae' COLLATE latin1_german2_ci |
+--------------------------------------+
|                                    1 |
+--------------------------------------+

特别是,尾随空格很重要,这对于使用=运算符执行的非二进制字符串(CHARVARCHARTEXT值)的比较不是正确的:

mysql> SELECT 'a' = 'a ', 'a' LIKE 'a ';
+------------+---------------+
| 'a' = 'a ' | 'a' LIKE 'a ' |
+------------+---------------+
|          1 |             0 |
+------------+---------------+
1 row in set (0.00 sec)

使用LIKE,您可以在模式中使用以下两个通配符:

  • %匹配任意数量的字符,甚至零个字符。

    • _完全匹配一个字符。
mysql> SELECT 'David!' LIKE 'David_';
        -> 1
mysql> SELECT 'David!' LIKE '%D%v%';
        -> 1

要测试通配符的 Literals 实例,请在其前面加上转义符。如果您未指定ESCAPE字符,则假定为\

  • \%匹配一个%字符。

    • \_匹配一个_字符。
mysql> SELECT 'David!' LIKE 'David\_';
        -> 0
mysql> SELECT 'David_' LIKE 'David\_';
        -> 1

要指定其他转义字符,请使用ESCAPE子句:

mysql> SELECT 'David_' LIKE 'David|_' ESCAPE '|';
        -> 1

转义序列应为空或一个字符长。该 table 达式在执行时必须计算为常量。如果启用了NO_BACKSLASH_ESCAPES SQL 模式,则序列不能为空。

以下两个语句说明,字符串比较不区分大小写,除非其中一个操作数区分大小写(使用区分大小写的归类或二进制字符串):

mysql> SELECT 'abc' LIKE 'ABC';
        -> 1
mysql> SELECT 'abc' LIKE _latin1 'ABC' COLLATE latin1_general_cs;
        -> 0
mysql> SELECT 'abc' LIKE _latin1 'ABC' COLLATE latin1_bin;
        -> 0
mysql> SELECT 'abc' LIKE BINARY 'ABC';
        -> 0

作为标准 SQL 的扩展,MySQL 允许在数字 table 达式上使用LIKE

mysql> SELECT 10 LIKE '1%';
        -> 1

Note

由于 MySQL 在字符串中使用 C 转义语法(例如\ntable 示换行符),因此您必须对在LIKE字符串中使用的任何\加倍。例如,要搜索\n,请将其指定为\\n。要搜索\,请将其指定为\\\\;这是因为解析器会一次删除反斜杠,而在进行模式匹配时会再次反斜杠,因此要匹配一个反斜杠。

exception:在模式字符串的末尾,反斜杠可以指定为\\。在字符串的末尾,反斜杠代 table 自身,因为没有其他内容可以逃脱。假设一个 table 包含以下值:

mysql> SELECT filename FROM t1;
+--------------+
| filename     |
+--------------+
| C:           |
| C:\          |
| C:\Programs  |
| C:\Programs\ |
+--------------+

要测试以反斜杠结尾的值,可以使用以下两种模式之一来匹配值:

mysql> SELECT filename, filename LIKE '%\\' FROM t1;
+--------------+---------------------+
| filename     | filename LIKE '%\\' |
+--------------+---------------------+
| C:           |                   0 |
| C:\          |                   1 |
| C:\Programs  |                   0 |
| C:\Programs\ |                   1 |
+--------------+---------------------+

mysql> SELECT filename, filename LIKE '%\\\\' FROM t1;
+--------------+-----------------------+
| filename     | filename LIKE '%\\\\' |
+--------------+-----------------------+
| C:           |                     0 |
| C:\          |                     1 |
| C:\Programs  |                     0 |
| C:\Programs\ |                     1 |
+--------------+-----------------------+

expr 不喜欢拍[ESCAPE'escape_char']

这与NOT (expr LIKE pat [ESCAPE 'escape_char'])相同。

Note

涉及NOT LIKE与包含NULL的列进行比较的聚合查询可能会产生意外结果。例如,考虑下 table 和数据:

CREATE TABLE foo (bar VARCHAR(10));

INSERT INTO foo VALUES (NULL), (NULL);

查询SELECT COUNT(*) FROM foo WHERE bar LIKE '%baz%';返回0。您可能假设SELECT COUNT(*) FROM foo WHERE bar NOT LIKE '%baz%';将返回2。但是,情况并非如此:第二个查询返回0。这是因为NULL NOT LIKE expr始终返回NULL,而不管* expr *的值如何。对于涉及NULL的聚合查询以及使用NOT RLIKENOT REGEXP进行的比较,也是如此。在这种情况下,必须使用OR(而不是AND)显式测试NOT NULL,如下所示:

SELECT COUNT(*) FROM foo WHERE bar NOT LIKE '%baz%' OR bar IS NULL;

STRCMP(expr1,expr2)

如果字符串相同,则STRCMP()返回0,如果根据当前排序 Sequences,第一个参数小于第二个参数,则-1,否则返回1

mysql> SELECT STRCMP('text', 'text2');
        -> -1
mysql> SELECT STRCMP('text2', 'text');
        -> 1
mysql> SELECT STRCMP('text', 'text');
        -> 0

STRCMP()使用参数的排序规则执行比较。

mysql> SET @s1 = _latin1 'x' COLLATE latin1_general_ci;
mysql> SET @s2 = _latin1 'X' COLLATE latin1_general_ci;
mysql> SET @s3 = _latin1 'x' COLLATE latin1_general_cs;
mysql> SET @s4 = _latin1 'X' COLLATE latin1_general_cs;
mysql> SELECT STRCMP(@s1, @s2), STRCMP(@s3, @s4);
+------------------+------------------+
| STRCMP(@s1, @s2) | STRCMP(@s3, @s4) |
+------------------+------------------+
|                0 |                1 |
+------------------+------------------+

如果排序规则不兼容,则必须将其中一个参数转换为与另一个兼容。参见第 10.8.4 节“table 达式中的排序规则强制性”

mysql> SELECT STRCMP(@s1, @s3);
ERROR 1267 (HY000): Illegal mix of collations (latin1_general_ci,IMPLICIT)
and (latin1_general_cs,IMPLICIT) for operation 'strcmp'
mysql> SELECT STRCMP(@s1, @s3 COLLATE latin1_general_ci);
+--------------------------------------------+
| STRCMP(@s1, @s3 COLLATE latin1_general_ci) |
+--------------------------------------------+
|                                          0 |
+--------------------------------------------+