Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  String Comparison Functions and Operators

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

表14.13 字符串比较函数和运算符

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

如果字符串函数传入的参数是一个二进制字符串,那么结果字符串也是一个二进制字符串。将数字转换为字符串时,结果字符串也是一个二进制字符串。这只影响比较。

通常,如果字符串比较中的任何表达式是大小写敏感的,那么比较将以大小写敏感的方式进行。

如果字符串函数在mysql客户端中被调用,二进制字符串将使用十六进制表示方式,取决于--binary-as-hex的值。有关该选项的更多信息,请参见第6.5.1节,“mysql — The MySQL Command-Line Client”

  • expr LIKE pat [ESCAPE 'escape_char']

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

    模式不需要是字面字符串。例如,它可以指定为字符串表达式或表列。在后一种情况下,列必须定义为 MySQL 字符串类型之一(见第13.3节,“String Data Types”)。

    根据 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 |
    +--------------------------------------+

    特别是,尾部空格总是有意义。这与使用=比较操作符时的尾部空格的重要性不同。有关更多信息,请参见Trailing Space Handling in Comparisons

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

    • % 匹配任意数量的字符,包括零个字符。

    • _ 匹配恰好一个字符。

    mysql> SELECT 'David!' LIKE 'David_';
            -> 1
    mysql> SELECT 'David!' LIKE '%D%v%';
            -> 1

    要测试通配符字符的字面值,precede 它以转义字符。如果您没有指定ESCAPE字符,\将被假定为转义字符,除非启用NO_BACKSLASH_ESCAPES SQL 模式。在这种情况下,不使用转义字符。

    • \% 匹配一个 % 字符。

    • \_ 匹配一个 _ 字符。

    mysql> SELECT 'David!' LIKE 'David\_';
            -> 0
    mysql> SELECT 'David_' LIKE 'David\_';
            -> 1

    要指定不同的转义字符,使用ESCAPE子句:

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

    转义序列应该是一个字符长,以指定转义字符,或者为空以指定不使用转义字符。表达式必须在执行时间评估为常数。如果启用NO_BACKSLASH_ESCAPES SQL 模式,序列不能为空。

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

    mysql> SELECT 'abc' LIKE 'ABC';
            -> 1
    mysql> SELECT 'abc' LIKE _utf8mb4 'ABC' COLLATE utf8mb4_0900_as_cs;
            -> 0
    mysql> SELECT 'abc' LIKE _utf8mb4 'ABC' COLLATE utf8mb4_bin;
            -> 0
    mysql> SELECT 'abc' LIKE BINARY 'ABC';
            -> 0

    作为标准 SQL 的扩展,MySQL 允许LIKE 在数字表达式上。

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

    在这种情况下,MySQL 尝试将表达式隐式转换为字符串。请参阅第14.3节,“表达式评估中的类型转换”

    Note

    MySQL 使用 C 转义语法在字符串中(例如,\n 表示换行符)。如果您想让LIKE 字符串包含字面值的\,您必须将其双倍。 (除非启用NO_BACKSLASH_ESCAPES SQL 模式,在这种情况下,不使用转义字符。) 例如,要搜索\n,指定它为\\n。要搜索\,指定它为\\\\;这因为解析器一次将反斜杠删除一次,然后在模式匹配时删除一次,留下单个反斜杠以匹配。

    例外:在模式字符串末尾,反斜杠可以指定为\\。在字符串末尾,反斜杠表示自己,因为没有以下内容要转义。假设有一张表包含以下值:

    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 NOT LIKE pat [ESCAPE 'escape_char']

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

    Note

    涉及NOT LIKE比较的聚合查询,可能会产生意外的结果。例如,考虑以下表和数据:

    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的值是什么。类似地,对于使用NOT RLIKENOT REGEXP的聚合查询,您必须使用OR(而不是AND),如以下所示:

    SELECT COUNT(*) FROM foo WHERE bar NOT LIKE '%baz%' OR bar IS NULL;
  • STRCMP(expr1,expr2)

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

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

    STRCMP()使用参数的排序顺序进行比较。

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

    如果排序顺序不兼容,一个参数必须被转换以与另一个兼容。见Section 12.8.4, “Collation Coercibility in Expressions”

    mysql> SET @s1 = _utf8mb4 'x' COLLATE utf8mb4_0900_ai_ci;
    mysql> SET @s2 = _utf8mb4 'X' COLLATE utf8mb4_0900_ai_ci;
    mysql> SET @s3 = _utf8mb4 'x' COLLATE utf8mb4_0900_as_cs;
    mysql> SET @s4 = _utf8mb4 'X' COLLATE utf8mb4_0900_as_cs;
    -->
    mysql> SELECT STRCMP(@s1, @s3);
    ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT)
    and (utf8mb4_0900_as_cs,IMPLICIT) for operation 'strcmp'
    mysql> SELECT STRCMP(@s1, @s3 COLLATE utf8mb4_0900_ai_ci);
    +---------------------------------------------+
    | STRCMP(@s1, @s3 COLLATE utf8mb4_0900_ai_ci) |
    +---------------------------------------------+
    |                                           0 |
    +---------------------------------------------+