# 12.13 位函数和运算符

表 12.17 位函数和运算符

姓名 描述
& 按位与
>> 右移
<< 左移
^ 按位异或
BIT_COUNT() 返回设置的位数
| 按位或
~ 位反转

位函数和运算符包括BIT_COUNT(), 位与(), 位或(), BIT_XOR(), &, |,^,~,<<, 和>>.(这位与(),位或(), 和BIT_XOR()聚合函数在第 12.20.1 节,“聚合函数描述”.) 在 MySQL 8.0 之前,需要位函数和运算符大整数(64 位整数)参数并返回大整数值,因此它们的最大范围为 64 位。非-大整数参数被转换为大整数在执行操作之前,可能会发生截断。

在 MySQL 8.0 中,位函数和运算符允许二进制字符串类型参数 (二进制,变量, 和斑点types) 并返回一个类似类型的值,这使它们能够接受参数并产生大于 64 位的返回值。非二进制字符串参数转换为大整数并像以前一样处理。

这种行为变化的一个含义是二进制字符串参数上的位操作可能在 MySQL 8.0 中产生与 5.7 不同的结果。有关如何在 MySQL 5.7 中为 MySQL 5.7 和 8.0 之间的潜在不兼容性做好准备的信息,请参阅位函数和运算符 (opens new window), 在MySQL 5.7 参考手册 (opens new window).

# MySQL 8.0 之前的位操作

MySQL 8.0 之前的位操作仅处理无符号的 64 位整数参数和结果值(即,无符号大整数值)。将其他类型的参数转换为大整数必要时发生。例子:

  • 此语句对数字文字进行操作,将其视为无符号 64 位整数:

    mysql> SELECT 127 | 128, 128 << 2, BIT_COUNT(15);
    +-----------+----------+---------------+
    | 127 | 128 | 128 << 2 | BIT_COUNT(15) |
    +-----------+----------+---------------+
    |       255 |      512 |             4 |
    +-----------+----------+---------------+
    
  • 此语句对字符串参数执行数字转换 ('127'127等)在执行与第一条语句相同的操作并产生相同结果之前:

    mysql> SELECT '127' | '128', '128' << 2, BIT_COUNT('15');
    +---------------+------------+-----------------+
    | '127' | '128' | '128' << 2 | BIT_COUNT('15') |
    +---------------+------------+-----------------+
    |           255 |        512 |               4 |
    +---------------+------------+-----------------+
    
  • 此语句对位操作参数使用十六进制文字。默认情况下,MySQL 将十六进制文字视为二进制字符串,但在数字上下文中将它们评估为数字(参见第 9.1.4 节,“十六进制文字”)。在 MySQL 8.0 之前,数字上下文包括位操作。例子:

    mysql> SELECT X'7F' | X'80', X'80' << 2, BIT_COUNT(X'0F');
    +---------------+------------+------------------+
    | X'7F' | X'80' | X'80' << 2 | BIT_COUNT(X'0F') |
    +---------------+------------+------------------+
    |           255 |        512 |                4 |
    +---------------+------------+------------------+
    

    位操作中位值文字的处理类似于十六进制文字(即作为数字)。

# MySQL 8.0 中的位操作

MySQL 8.0 扩展了位操作以直接处理二进制字符串参数(无需转换)并产生二进制字符串结果。(不是整数或二进制字符串的参数仍会像以前一样转换为整数。)此扩展通过以下方式增强位操作:

  • 对超过 64 位的值进行位操作成为可能。

  • 对更自然地表示为二进制字符串而不是整数的值执行位操作更容易。

    例如,考虑 UUID 值和 IPv6 地址,它们具有人类可读的文本格式,如下所示:

UUID: 6ccd780c-baba-1026-9564-5b8c656024db
IPv6: fe80::219:d1ff:fe91:1a72

对这些格式的文本字符串进行操作很麻烦。另一种方法是将它们转换为不带分隔符的固定长度二进制字符串。UUID_TO_BIN()INET6_ATON()每个产生一个数据类型的值二进制(16),一个 16 字节(128 位)长的二进制字符串。以下陈述说明了这一点(十六进制()用于产生可显示的值):

mysql> SELECT HEX(UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db'));
+----------------------------------------------------------+
| HEX(UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db')) |
+----------------------------------------------------------+
| 6CCD780CBABA102695645B8C656024DB                         |
+----------------------------------------------------------+
mysql> SELECT HEX(INET6_ATON('fe80::219:d1ff:fe91:1a72'));
+---------------------------------------------+
| HEX(INET6_ATON('fe80::219:d1ff:fe91:1a72')) |
+---------------------------------------------+
| FE800000000000000219D1FFFE911A72            |
+---------------------------------------------+

这些二进制值很容易通过位操作进行操作,以执行诸如从 UUID 值中提取时间戳或提取 IPv6 地址的网络和主机部分等操作。(例如,请参阅本讨论后面的内容。)

算作二进制字符串的参数包括列值、例程参数、局部变量和具有二进制字符串类型的用户定义变量:二进制,变量,或其中之一斑点类型。

十六进制文字和位文字呢?回想一下,在 MySQL 中默认情况下这些是二进制字符串,但在数字上下文中是数字。在 MySQL 8.0 中,它们是如何处理位操作的?MySQL 是否继续在数字上下文中评估它们,就像 MySQL 8.0 之前所做的那样?还是位操作将它们评估为二进制字符串,现在二进制字符串可以“本地”处理而无需转换?

答:通常使用十六进制文字或位文字为位操作指定参数以表示数字,因此当所有位参数都是十六进制或位文字时,MySQL 继续在数字上下文中评估位操作,以实现向后兼容性。如果您需要评估为二进制字符串,这很容易实现:使用_二进制至少一种文字的介绍人。

  • 这些位运算将十六进制文字和位文字评估为整数:

    mysql> SELECT X'40' | X'01', b'11110001' & b'01001111';
    +---------------+---------------------------+
    | X'40' | X'01' | b'11110001' & b'01001111' |
    +---------------+---------------------------+
    |            65 |                        65 |
    +---------------+---------------------------+
    
  • 这些位运算将十六进制文字和位文字评估为二进制字符串,因为_二进制介绍人:

    mysql> SELECT _binary X'40' | X'01', b'11110001' & _binary b'01001111';
    +-----------------------+-----------------------------------+
    | _binary X'40' | X'01' | b'11110001' & _binary b'01001111' |
    +-----------------------+-----------------------------------+
    | A                     | A                                 |
    +-----------------------+-----------------------------------+
    

    虽然这两个语句中的位运算产生的结果是数值 65,但第二个语句在二进制字符串上下文中运行,其中 65 是 ASCII一种.

    在数值计算上下文中,十六进制文字和位文字参数的允许值最多为 64 位,结果也是如此。相比之下,在二进制字符串评估上下文中,允许的参数(和结果)可以超过 64 位:

mysql> SELECT _binary X'4040404040404040' | X'0102030405060708';
+---------------------------------------------------+
| _binary X'4040404040404040' | X'0102030405060708' |
+---------------------------------------------------+
| ABCDEFGH                                          |
+---------------------------------------------------+

有几种方法可以在位操作中引用十六进制文字或位文字以导致二进制字符串评估:

_binary literal
BINARY literal
CAST(literal AS BINARY)

生成十六进制文字或位文字的二进制字符串评估的另一种方法是将它们分配给用户定义的变量,这会产生具有二进制字符串类型的变量:

mysql> SET @v1 = X'40', @v2 = X'01', @v3 = b'11110001', @v4 = b'01001111';
mysql> SELECT @v1 | @v2, @v3 & @v4;
+-----------+-----------+
| @v1 | @v2 | @v3 & @v4 |
+-----------+-----------+
| A         | A         |
+-----------+-----------+

在二进制字符串上下文中,按位运算参数必须具有相同的长度或ER_INVALID_BITWISE_OPERANDS_SIZE (opens new window)发生错误:

mysql> SELECT _binary X'40' | X'0001';
ERROR 3513 (HY000): Binary operands of bitwise
operators must be of equal length

为了满足等长要求,用前导零数字填充较短的值,或者,如果较长的值以前导零数字开头并且可以接受较短的结果值,则将它们剥离:

mysql> SELECT _binary X'0040' | X'0001';
+---------------------------+
| _binary X'0040' | X'0001' |
+---------------------------+
|  A                        |
+---------------------------+
mysql> SELECT _binary X'40' | X'01';
+-----------------------+
| _binary X'40' | X'01' |
+-----------------------+
| A                     |
+-----------------------+

填充或剥离也可以使用诸如LPAD(),RPAD(),SUBSTR(), 要么投掷().在这种情况下,表达式参数不再都是文字,并且_二进制变得不必要。例子:

mysql> SELECT LPAD(X'40', 2, X'00') | X'0001';
+---------------------------------+
| LPAD(X'40', 2, X'00') | X'0001' |
+---------------------------------+
|  A                              |
+---------------------------------+
mysql> SELECT X'40' | SUBSTR(X'0001', 2, 1);
+-------------------------------+
| X'40' | SUBSTR(X'0001', 2, 1) |
+-------------------------------+
| A                             |
+-------------------------------+

# 二进制字符串位操作示例

以下示例说明了使用位操作来提取 UUID 值的一部分,在这种情况下,是时间戳和 IEEE 802 节点号。此技术需要每个提取部分的位掩码。

将文本 UUID 转换为相应的 16 字节二进制值,以便可以在二进制字符串上下文中使用位操作对其进行操作:

mysql> SET @uuid = UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db');
mysql> SELECT HEX(@uuid);
+----------------------------------+
| HEX(@uuid)                       |
+----------------------------------+
| 6CCD780CBABA102695645B8C656024DB |
+----------------------------------+

为值的时间戳和节点号部分构造位掩码。时间戳包括前三部分(64 位,位 0 到 63),节点号是最后部分(48 位,位 80 到 127):

mysql> SET @ts_mask = CAST(X'FFFFFFFFFFFFFFFF' AS BINARY(16));
mysql> SET @node_mask = CAST(X'FFFFFFFFFFFF' AS BINARY(16)) >> 80;
mysql> SELECT HEX(@ts_mask);
+----------------------------------+
| HEX(@ts_mask)                    |
+----------------------------------+
| FFFFFFFFFFFFFFFF0000000000000000 |
+----------------------------------+
mysql> SELECT HEX(@node_mask);
+----------------------------------+
| HEX(@node_mask)                  |
+----------------------------------+
| 00000000000000000000FFFFFFFFFFFF |
+----------------------------------+

演员(...作为二进制(16))此处使用函数是因为掩码的长度必须与应用它们的 UUID 值相同。使用其他函数将掩码填充到所需长度可以产生相同的结果:

SET @ts_mask= RPAD(X'FFFFFFFFFFFFFFFF' , 16, X'00');
SET @node_mask = LPAD(X'FFFFFFFFFFFF', 16, X'00') ;

使用掩码提取时间戳和节点编号部分:

mysql> SELECT HEX(@uuid & @ts_mask) AS 'timestamp part';
+----------------------------------+
| timestamp part                   |
+----------------------------------+
| 6CCD780CBABA10260000000000000000 |
+----------------------------------+
mysql> SELECT HEX(@uuid & @node_mask) AS 'node part';
+----------------------------------+
| node part                        |
+----------------------------------+
| 000000000000000000005B8C656024DB |
+----------------------------------+

前面的示例使用这些位操作:右移 (>>) 和按位与 (&)。

笔记

UUID_TO_BIN()接受一个标志,该标志会导致生成的二进制 UUID 值中的一些位重新排列。如果您使用该标志,请相应地修改提取掩码。

下一个示例使用位操作来提取 IPv6 地址的网络和主机部分。假设网络部分的长度为 80 位。那么主机部分的长度为 128 - 80 = 48 位。要提取地址的网络和主机部分,请将其转换为二进制字符串,然后在二进制字符串上下文中使用位操作。

将文本 IPv6 地址转换为相应的二进制字符串:

mysql> SET @ip = INET6_ATON('fe80::219:d1ff:fe91:1a72');

以比特为单位定义网络长度:

mysql> SET @net_len = 80;

通过向左或向右移动全为地址来构造网络和主机掩码。为此,请从地址开始::,这是全零的简写,您可以通过将其转换为如下所示的二进制字符串来看到:

mysql> SELECT HEX(INET6_ATON('::')) AS 'all zeros';
+----------------------------------+
| all zeros                        |
+----------------------------------+
| 00000000000000000000000000000000 |
+----------------------------------+

要产生互补值(全为),请使用~运算符反转位:

mysql> SELECT HEX(~INET6_ATON('::')) AS 'all ones';
+----------------------------------+
| all ones                         |
+----------------------------------+
| FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
+----------------------------------+

向左或向右移动全为值以生成网络和主机掩码:

mysql> SET @net_mask = ~INET6_ATON('::') << (128 - @net_len);
mysql> SET @host_mask = ~INET6_ATON('::') >> @net_len;

显示掩码以验证它们是否覆盖了地址的正确部分:

mysql> SELECT INET6_NTOA(@net_mask) AS 'network mask';
+----------------------------+
| network mask               |
+----------------------------+
| ffff:ffff:ffff:ffff:ffff:: |
+----------------------------+
mysql> SELECT INET6_NTOA(@host_mask) AS 'host mask';
+------------------------+
| host mask              |
+------------------------+
| ::ffff:255.255.255.255 |
+------------------------+

提取并显示地址的网络和主机部分:

mysql> SET @net_part = @ip & @net_mask;
mysql> SET @host_part = @ip & @host_mask;
mysql> SELECT INET6_NTOA(@net_part) AS 'network part';
+-----------------+
| network part    |
+-----------------+
| fe80::219:0:0:0 |
+-----------------+
mysql> SELECT INET6_NTOA(@host_part) AS 'host part';
+------------------+
| host part        |
+------------------+
| ::d1ff:fe91:1a72 |
+------------------+

前面的示例使用这些位操作: 补 (~), 左移 (<<) 和按位与 (&)。

剩下的讨论提供了有关每组位操作的参数处理的详细信息,有关位操作中的字面值处理的更多信息,以及 MySQL 8.0 和旧 MySQL 版本之间的潜在不兼容性。

# 按位与、或和异或运算

为了&,|, 和^位操作,结果类型取决于参数是二进制字符串还是数字:

  • 当参数具有二进制字符串类型并且其中至少一个不是十六进制文字、位文字或空值文字。否则会进行数值计算,必要时将参数转换为无符号 64 位整数。

  • 二进制字符串求值产生一个与参数长度相同的二进制字符串。如果参数的长度不相等,则ER_INVALID_BITWISE_OPERANDS_SIZE (opens new window)发生错误。数值计算产生一个无符号的 64 位整数。

    数值评估的例子:

mysql> SELECT 64 | 1, X'40' | X'01';
+--------+---------------+
| 64 | 1 | X'40' | X'01' |
+--------+---------------+
|     65 |            65 |
+--------+---------------+

二进制字符串评估示例:

mysql> SELECT _binary X'40' | X'01';
+-----------------------+
| _binary X'40' | X'01' |
+-----------------------+
| A                     |
+-----------------------+
mysql> SET @var1 = X'40', @var2 = X'01';
mysql> SELECT @var1 | @var2;
+---------------+
| @var1 | @var2 |
+---------------+
| A             |
+---------------+

# 按位补码和移位操作

为了~,<<, 和>>位操作,结果类型取决于位参数是否被评估为二进制字符串或数字:

  • 当位参数具有二进制字符串类型并且不是十六进制文字、位文字或空值文字。否则会进行数值计算,必要时将参数转换为无符号 64 位整数。

  • 二进制字符串求值产生与位参数长度相同的二进制字符串。数值计算产生一个无符号的 64 位整数。

    对于移位操作,无论参数类型如何,移出值末尾的位都会在没有警告的情况下丢失。特别是,如果移位计数大于或等于位参数中的位数,则结果中的所有位均为 0。

    数值评估的例子:

mysql> SELECT ~0, 64 << 2, X'40' << 2;
+----------------------+---------+------------+
| ~0                   | 64 << 2 | X'40' << 2 |
+----------------------+---------+------------+
| 18446744073709551615 |     256 |        256 |
+----------------------+---------+------------+

二进制字符串评估示例:

mysql> SELECT HEX(_binary X'1111000022220000' >> 16);
+----------------------------------------+
| HEX(_binary X'1111000022220000' >> 16) |
+----------------------------------------+
| 0000111100002222                       |
+----------------------------------------+
mysql> SELECT HEX(_binary X'1111000022220000' << 16);
+----------------------------------------+
| HEX(_binary X'1111000022220000' << 16) |
+----------------------------------------+
| 0000222200000000                       |
+----------------------------------------+
mysql> SET @var1 = X'F0F0F0F0';
mysql> SELECT HEX(~@var1);
+-------------+
| HEX(~@var1) |
+-------------+
| 0F0F0F0F    |
+-------------+

# 少量_计数()操作

BIT_COUNT()函数总是返回一个无符号的 64 位整数,或者空值如果参数是空值.

mysql> SELECT BIT_COUNT(127);
+----------------+
| BIT_COUNT(127) |
+----------------+
|              7 |
+----------------+
mysql> SELECT BIT_COUNT(b'010101'), BIT_COUNT(_binary b'010101');
+----------------------+------------------------------+
| BIT_COUNT(b'010101') | BIT_COUNT(_binary b'010101') |
+----------------------+------------------------------+
|                    3 |                            3 |
+----------------------+------------------------------+

# 少量_与(),位_OR() 和 BIT_XOR() 操作

为了位与(),位或(), 和BIT_XOR()位函数,结果类型取决于函数参数值是二进制字符串还是数字:

空值值不会影响结果,除非所有值都空值.在这种情况下,结果是一个中性值,其长度与参数值的长度相同(所有位为 1位与(), 所有位 0 为位或(), 和BIT_XOR())。

例子:

mysql> CREATE TABLE t (group_id INT, a VARBINARY(6));
mysql> INSERT INTO t VALUES (1, NULL);
mysql> INSERT INTO t VALUES (1, NULL);
mysql> INSERT INTO t VALUES (2, NULL);
mysql> INSERT INTO t VALUES (2, X'1234');
mysql> INSERT INTO t VALUES (2, X'FF34');
mysql> SELECT HEX(BIT_AND(a)), HEX(BIT_OR(a)), HEX(BIT_XOR(a))
       FROM t GROUP BY group_id;
+-----------------+----------------+-----------------+
| HEX(BIT_AND(a)) | HEX(BIT_OR(a)) | HEX(BIT_XOR(a)) |
+-----------------+----------------+-----------------+
| FFFFFFFFFFFF    | 000000000000   | 000000000000    |
| 1234            | FF34           | ED00            |
+-----------------+----------------+-----------------+

# 十六进制文字、位文字和 NULL 的特殊处理

字面量

为了向后兼容,当所有位参数都是十六进制字面量、位字面量或空值文字。也就是说,如果所有位参数都是未经修饰的十六进制文字、位文字或空值文字。(这不适用于这样的文字,如果它们是用_二进制介绍人,二进制运算符,或以其他方式将它们显式指定为二进制字符串。)

刚刚描述的文字处理与 MySQL 8.0 之前的相同。例子:

  • 这些位操作在数字上下文中评估文字并产生大整数结果:

    b'0001' | b'0010'
    X'0008' << 8
    
  • 这些位操作评估空值在数字上下文中并产生一个大整数结果有空值价值:

    NULL & NULL
    NULL >> 4
    

    在 MySQL 8.0 中,您可以通过显式指示至少一个参数是二进制字符串来使这些操作在二进制字符串上下文中评估参数:

_binary b'0001' | b'0010'
_binary X'0008' << 8
BINARY NULL & NULL
BINARY NULL >> 4

最后两个表达式的结果是空值, 就像没有二进制运算符,但结果的数据类型是二进制字符串类型而不是整数类型。

# 位操作与 MySQL 5.7 不兼容

因为位操作可以在 MySQL 8.0 中本地处理二进制字符串参数,所以某些表达式在 MySQL 8.0 中产生的结果与在 5.7 中不同。需要注意的五种有问题的表达式类型是:

nonliteral_binary { & | ^ } binary
binary  { & | ^ } nonliteral_binary
nonliteral_binary { << >> } anything
~ nonliteral_binary
AGGR_BIT_FUNC(nonliteral_binary)

那些表达式返回大整数在 MySQL 5.7 中,8.0 中的二进制字符串。

符号解释:

  • { *op1* *op2* ... }:适用于给定表达式类型的运算符列表。

  • 二进制: 任何类型的二进制字符串参数,包括十六进制文字、位文字或空值文字。

  • nonliteral_binary: 一个二进制字符串值的参数,而不是十六进制文字、位文字或空值文字。

  • AGGR_BIT_FUNC:一个接受位值参数的聚合函数:位与(), 位或(), BIT_XOR().

    有关如何在 MySQL 5.7 中为 MySQL 5.7 和 8.0 之间的潜在不兼容性做好准备的信息,请参阅位函数和运算符 (opens new window), 在MySQL 5.7 参考手册 (opens new window).

    以下列表描述了可用的位函数和运算符:

  • |

    按位或。

    结果类型取决于参数是否被评估为二进制字符串或数字:

    • 当参数具有二进制字符串类型并且其中至少一个不是十六进制文字、位文字或空值文字。否则会进行数值计算,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串求值产生一个与参数长度相同的二进制字符串。如果参数的长度不相等,则ER_INVALID_BITWISE_OPERANDS_SIZE (opens new window)发生错误。数值计算产生一个无符号的 64 位整数。

      有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 29 | 15;
            -> 31
    mysql> SELECT _binary X'40404040' | X'01020304';
            -> 'ABCD'
    

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

  • &

    按位与。

    结果类型取决于参数是否被评估为二进制字符串或数字:

    • 当参数具有二进制字符串类型并且其中至少一个不是十六进制文字、位文字或空值文字。否则会进行数值计算,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串求值产生一个与参数长度相同的二进制字符串。如果参数的长度不相等,则ER_INVALID_BITWISE_OPERANDS_SIZE (opens new window)发生错误。数值计算产生一个无符号的 64 位整数。

      有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 29 & 15;
            -> 13
    mysql> SELECT HEX(_binary X'FF' & b'11110000');
            -> 'F0'
    

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

  • ^

    按位异或。

    结果类型取决于参数是否被评估为二进制字符串或数字:

    • 当参数具有二进制字符串类型并且其中至少一个不是十六进制文字、位文字或空值文字。否则会进行数值计算,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串求值产生一个与参数长度相同的二进制字符串。如果参数的长度不相等,则ER_INVALID_BITWISE_OPERANDS_SIZE (opens new window)发生错误。数值计算产生一个无符号的 64 位整数。

      有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 1 ^ 1;
            -> 0
    mysql> SELECT 1 ^ 0;
            -> 1
    mysql> SELECT 11 ^ 3;
            -> 8
    mysql> SELECT HEX(_binary X'FEDC' ^ X'1111');
            -> 'EFCD'
    

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

  • <<

    移位很长(大整数) 左边的数字或二进制字符串。

    结果类型取决于 bit 参数是否被评估为二进制字符串或数字:

    • 当位参数具有二进制字符串类型并且不是十六进制文字、位文字或空值文字。否则会进行数值计算,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串求值产生与位参数长度相同的二进制字符串。数值计算产生一个无符号的 64 位整数。

      无论参数类型如何,移出值末尾的位都会在没有警告的情况下丢失。特别是,如果移位计数大于或等于位参数中的位数,则结果中的所有位均为 0。

      有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 1 << 2;
            -> 4
    mysql> SELECT HEX(_binary X'00FF00FF00FF' << 8);
            -> 'FF00FF00FF00'
    

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

  • >>

    移位很长(大整数) 右边的数字或二进制字符串。

    结果类型取决于 bit 参数是否被评估为二进制字符串或数字:

    • 当位参数具有二进制字符串类型并且不是十六进制文字、位文字或空值文字。否则会进行数值计算,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串求值产生与位参数长度相同的二进制字符串。数值计算产生一个无符号的 64 位整数。

      无论参数类型如何,移出值末尾的位都会在没有警告的情况下丢失。特别是,如果移位计数大于或等于位参数中的位数,则结果中的所有位均为 0。

      有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 4 >> 2;
            -> 1
    mysql> SELECT HEX(_binary X'00FF00FF00FF' >> 8);
            -> '0000FF00FF00'
    

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

  • ~

    反转所有位。

    结果类型取决于 bit 参数是否被评估为二进制字符串或数字:

    • 当位参数具有二进制字符串类型并且不是十六进制文字、位文字或空值文字。否则会进行数值计算,必要时将参数转换为无符号 64 位整数。

    • 二进制字符串求值产生与位参数长度相同的二进制字符串。数值计算产生一个无符号的 64 位整数。

      有关详细信息,请参阅本节中的介绍性讨论。

    mysql> SELECT 5 & ~1;
            -> 4
    mysql> SELECT HEX(~X'0000FFFF1111EEEE');
            -> 'FFFF0000EEEE1111'
    

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

  • BIT_COUNT(*ñ*)

    返回参数中设置的位数*ñ*作为无符号 64 位整数,或空值如果参数是空值.

    mysql> SELECT BIT_COUNT(64), BIT_COUNT(BINARY 64);
            -> 1, 7
    mysql> SELECT BIT_COUNT('64'), BIT_COUNT(_binary '64');
            -> 1, 7
    mysql> SELECT BIT_COUNT(X'40'), BIT_COUNT(_binary X'40');
            -> 1, 1