文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  字符串比较函数和运算符

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

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

名称 描述
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 节,“字符串数据类型”)。

    根据 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 值)中尾随空格的有效性取决于用于比较的排序规则的填充属性。有关更多信息,请参见 比较中的尾随空格处理

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

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

    • _ 匹配一个字符。

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

    要测试通配符的文字实例,请在它前面加上转义字符。如果您没有指定 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 节,“表达式求值中的类型转换”

    注意

    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']) 相同。

    注意

    涉及 NULL 的列的 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 的值是什么。对于涉及 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,如果第一个参数小于第二个参数(根据当前排序顺序),则返回 -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 |
    +------------------+------------------+

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

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