12.7.1 字符串比较函数和运算符
table12.12 字符串比较函数和运算符
Name | Description |
---|---|
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 |
+--------------------------------------+
特别是,尾随空格很重要,这对于使用=运算符执行的非二进制字符串(CHAR
,VARCHAR
和TEXT
值)的比较不是正确的:
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 转义语法(例如\n
table 示换行符),因此您必须对在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 RLIKE或NOT REGEXP进行的比较,也是如此。在这种情况下,必须使用OR(而不是AND)显式测试NOT NULL
,如下所示:
SELECT COUNT(*) FROM foo WHERE bar NOT LIKE '%baz%' OR bar IS NULL;
如果字符串相同,则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 |
+--------------------------------------------+