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

[](<>)[](<>)[](<>)[](<>)

[](<>)

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

| 姓名 | 描述 |
| --- | --- |
| [`喜欢`](string-comparison-functions.html#operator_like) | 简单的模式匹配 |
| [`不喜欢`](string-comparison-functions.html#operator_not-like) | 简单模式匹配的否定 |
| [`STRCMP()`](string-comparison-functions.html#function_strcmp) | 比较两个字符串 |

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

[](<>)[](<>)

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

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

-   [](<>)

    [`*`表达式`* 喜欢 *`拍`* [逃脱 '*`escape_char`*']`](string-comparison-functions.html#operator_like)

    [](<>)

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

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

    根据 SQL 标准，[`喜欢`](string-comparison-functions.html#operator_like)基于每个字符执行匹配，因此它可以产生不同于[`=`](comparison-operators.html#operator_equal)比较运算符：

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

    [](<>)

    特别是，尾随空格总是很重要。这不同于与[`=`](comparison-operators.html#operator_equal)运算符，对于非二进制字符串中尾随空格的重要性 (`字符`,`VARCHAR`， 和`文本`values) 取决于用于比较的排序规则的 pad 属性。有关详细信息，请参阅[比较中的尾随空间处理](charset-binary-collations.html#charset-binary-collations-trailing-space-comparisons).

    和[`喜欢`](string-comparison-functions.html#operator_like)您可以在模式中使用以下两个通配符：

    -   `%`匹配任意数量的字符，甚至是零个字符。

    -   `_`只匹配一个字符。

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

    要测试通配符的文字实例，请在其前面加上转义字符。如果您不指定`逃脱`特点，`\`假定，除非[`NO_BACKSLASH_ESCAPE`](sql-mode.html#sqlmode_no_backslash_escapes)SQL 模式已启用。在这种情况下，不使用转义字符。

    -   `\%`匹配一个`%`特点。

    -   `\_`匹配一个`_`特点。

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

    要指定不同的转义字符，请使用`逃脱`条款：

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

    转义序列应为一个字符长以指定转义字符，或为空以指定不使用转义字符。表达式必须在执行时计算为常量。如果[`NO_BACKSLASH_ESCAPE`](sql-mode.html#sqlmode_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 允许[`喜欢`](string-comparison-functions.html#operator_like)关于数值表达式。

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

    笔记

    MySQL 在字符串中使用 C 转义语法（例如，`\n`表示换行符）。如果你想要一个[`喜欢`](string-comparison-functions.html#operator_like)包含文字的字符串`\`，你必须加倍。（除非[`NO_BACKSLASH_ESCAPE`](sql-mode.html#sqlmode_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 |
    +--------------+-----------------------+
    ```

-   [](<>)

    [`*`表达式`* 不喜欢 *`拍`* [逃脱 '*`escape_char`*']`](string-comparison-functions.html#operator_not-like)

    [](<>)

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

    笔记

    聚合查询涉及[`不喜欢`](string-comparison-functions.html#operator_not-like)与包含的列进行比较`空值`可能会产生意想不到的结果。例如，考虑下表和数据：

    ```
    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 不喜欢 *`表达式`*`总是返回`空值`, 不管值*`表达式`*.对于涉及的聚合查询也是如此`空值`和比较使用[`不喜欢`](regexp.html#operator_not-regexp)要么[`不是正则表达式`](regexp.html#operator_not-regexp).在这种情况下，您必须明确测试`非空`使用[`要么`](logical-operators.html#operator_or)（并不是[`和`](logical-operators.html#operator_and))，如下所示：

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

-   [](<>)

    [`STRCMP(*`expr1`*,*`expr2`*)`](string-comparison-functions.html#function_strcmp)

    [](<>)

    [`STRCMP()`](string-comparison-functions.html#function_strcmp)返回`0`如果字符串相同，`-1`如果根据当前排序顺序，第一个参数小于第二个参数，并且`1`否则。

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

    [`STRCMP()`](string-comparison-functions.html#function_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 节，“表达式中的排序规则强制性”](charset-collation-coercibility.html).

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