# 12.8.1 字符串比较函数和运算符

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

姓名 描述
喜欢 简单的模式匹配
不喜欢 简单模式匹配的否定
STRCMP() 比较两个字符串

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

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

如果从内部调用字符串函数mysql客户端,二进制字符串使用十六进制表示法显示,具体取决于--binary-as-hex.有关该选项的更多信息,请参阅第 4.5.1 节,“mysql - MySQL 命令行客户端”.

  • *表达式* 喜欢 ** [逃脱 '*escape_char*']

    使用 SQL 模式进行模式匹配。退货1(真的) 要么0(错误的)。如果要么*表达式要么*是空值,结果是空值.

    模式不必是文字字符串。例如,它可以指定为字符串表达式或表格列。在后一种情况下,列必须定义为 MySQL 字符串类型之一(请参阅第 11.3 节,“字符串数据类型”)。

    根据 SQL 标准,喜欢基于每个字符执行匹配,因此它可以产生不同于=比较运算符:

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

    特别是,尾随空格总是很重要。这不同于与=运算符,对于非二进制字符串中尾随空格的重要性 (字符,VARCHAR, 和文本values) 取决于用于比较的排序规则的 pad 属性。有关详细信息,请参阅比较中的尾随空间处理.

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

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

    • _只匹配一个字符。

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

    要测试通配符的文字实例,请在其前面加上转义字符。如果您不指定逃脱特点,\假定,除非NO_BACKSLASH_ESCAPESQL 模式已启用。在这种情况下,不使用转义字符。

    • \%匹配一个%特点。

    • \_匹配一个_特点。

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

    要指定不同的转义字符,请使用逃脱条款:

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

    转义序列应为一个字符长以指定转义字符,或为空以指定不使用转义字符。表达式必须在执行时计算为常量。如果NO_BACKSLASH_ESCAPE开启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 允许喜欢关于数值表达式。

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

    笔记

    MySQL 在字符串中使用 C 转义语法(例如,\n表示换行符)。如果你想要一个喜欢包含文字的字符串\,你必须加倍。(除非NO_BACKSLASH_ESCAPE启用 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 |
    +--------------+-----------------------+
    
  • *表达式* 不喜欢 ** [逃脱 '*escape_char*']

    这与不是 (*表达式* 喜欢 ** [逃脱 '*escape_char*']).

    笔记

    聚合查询涉及不喜欢与包含的列进行比较空值可能会产生意想不到的结果。例如,考虑下表和数据:

    CREATE TABLE foo (bar VARCHAR(10));
    
    INSERT INTO foo VALUES (NULL), (NULL);
    

    查询SELECT COUNT(*) FROM WHERE bar LIKE '%baz%';返回0.你可能会认为SELECT COUNT(*) FROM WHERE bar NOT LIKE '%baz%';会回来2.但是,情况并非如此:第二个查询返回0.这是因为NULL 不喜欢 *表达式*总是返回空值, 不管值*表达式*.对于涉及的聚合查询也是如此空值和比较使用不喜欢要么不是正则表达式.在这种情况下,您必须明确测试非空使用要么(并不是),如下所示:

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

    STRCMP()返回0如果字符串相同,-1如果根据当前排序顺序,第一个参数小于第二个参数,并且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 |
    +------------------+------------------+
    

    如果排序规则不兼容,则必须将其中一个参数转换为与另一个兼容。看第 10.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 |
    +---------------------------------------------+