Documentation Home
MySQL 8.0 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 36.1Mb
PDF (A4) - 36.2Mb


MySQL 8.0 リファレンスマニュアル  /  関数と演算子  /  ビット関数と演算子

このページは機械翻訳したものです。

12.13 ビット関数と演算子

表 12.17 「ビット関数と演算子」

名前 説明
& ビット単位の AND
>> 右シフト
<< 左シフト
^ ビット単位の XOR
BIT_COUNT() 設定されているビット数を返します
| ビット単位の OR
~ ビット単位の反転

ビット関数および演算子は、BIT_COUNT(), BIT_AND(), BIT_OR(), BIT_XOR(), &, |, ^, ~, << および >> で構成されます。 (BIT_AND()BIT_OR() および BIT_XOR() の集計関数については、セクション12.20.1「集計関数の説明」 を参照してください。) MySQL 8.0 より前では、ビット関数および演算子には BIGINT (64-bit 整数) 引数が必要であり、BIGINT 値が返されるため、最大範囲は 64 ビットでした。 操作の実行前に BIGINT 以外の引数が BIGINT に変換され、切捨てが発生する可能性があります。

MySQL 8.0 では、ビット関数および演算子はバイナリ文字列型の引数 (BINARYVARBINARY および BLOB 型) を許可し、同様の型の値を返します。これにより、引数を受け取り、64 ビットを超える戻り値を生成できます。 バイナリ以外の文字列引数は BIGINT に変換され、以前と同様に処理されます。

この動作の変更の影響は、バイナリ文字列引数に対するビット操作によって、MySQL 8.0 と 5.7 では異なる結果が生成される可能性があることです。 MySQL 5.7 と 8.0 間の潜在的な非互換性のために MySQL 5.7 で準備する方法の詳細は、MySQL 5.7 Reference ManualBit Functions and Operators を参照してください。

MySQL 8.0 より前のビット操作

MySQL 8.0 より前のビット操作では、符号なし 64 ビット整数引数と結果値 (つまり、符号なし BIGINT 値) のみが処理されます。 他の型の引数の BIGINT への変換は、必要に応じて行われます。 例:

  • 次のステートメントは、符号なし 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 |
    +---------------+------------+-----------------+
  • このステートメントは、ビット演算引数に 16 進数リテラルを使用します。 MySQL では、デフォルトで 16 進リテラルはバイナリ文字列として扱われますが、数値コンテキストでは数値として評価されます (セクション9.1.4「16 進数リテラル」 を参照)。 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 |
    +---------------+------------+------------------+

    ビット演算でのビット値リテラルの処理は、16 進数リテラル (つまり、数値) と似ています。

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 バイト (128 ビット) の長さのデータ型 BINARY(16) の値を生成します。 次のステートメントは、これを示しています (HEX() は表示可能な値を生成するために使用されます):

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 アドレスのネットワークおよびホスト部分の抽出などのアクションを実行するビット操作で簡単に指定できます。 (例については、この説明の後半のを参照してください。)

バイナリ文字列としてカウントされる引数には、カラム値、ルーチンパラメータ、ローカル変数、およびバイナリ文字列型を持つユーザー定義変数が含まれます: BINARYVARBINARY、またはいずれかの BLOB タイプ。

16 進数リテラルとビットリテラルについて これらは MySQL ではデフォルトでバイナリ文字列ですが、数値コンテキストの数値であることを思い出してください。 MySQL 8.0 では、ビット操作はどのように処理されますか。 MySQL は、MySQL 8.0 の前と同様に、引き続き数値コンテキストで評価しますか。 または、ビット操作によってバイナリ文字列として評価され、バイナリ文字列を変換せずに「ネイティブ」を処理できるようになりましたか。

回答: 16 進数リテラルまたはビットリテラルを使用してビット操作の引数を指定することは一般的であり、これらは数値を表すことを意図しているため、MySQL では、下位互換性のために、すべてのビット引数が 16 進数リテラルまたはビットリテラルである場合に、数値コンテキストでビット操作が評価され続けます。 かわりにバイナリ文字列としての評価が必要な場合は、簡単に実行できます: 少なくとも 1 つのリテラルに_binary イントロデューサを使用します。

  • 次のビット演算は、16 進数リテラルおよびビットリテラルを整数として評価します:

    mysql> SELECT X'40' | X'01', b'11110001' & b'01001111';
    +---------------+---------------------------+
    | X'40' | X'01' | b'11110001' & b'01001111' |
    +---------------+---------------------------+
    |            65 |                        65 |
    +---------------+---------------------------+
  • これらのビット操作では、_binary イントロデューサのために 16 進数リテラルおよびビットリテラルがバイナリ文字列として評価されます:

    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 の結果が生成されますが、2 番目のステートメントはバイナリ文字列コンテキスト (65 は ASCII A) で動作します。

数値評価コンテキストでは、16 進数リテラルおよびビットリテラル引数の許容値は、結果と同様に最大 64 ビットです。 対照的に、バイナリ文字列の評価コンテキストでは、許可される引数 (および結果) は 64 ビットを超えることができます:

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

ビット演算で 16 進数リテラルまたはビットリテラルを参照してバイナリ文字列評価を行うには、いくつかの方法があります:

_binary literal
BINARY literal
CAST(literal AS BINARY)

16 進数リテラルまたはビットリテラルの二項文字列評価を生成する別の方法は、それらをユーザー定義変数に割り当てることです。これにより、バイナリ文字列型の変数が生成されます:

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 エラーが発生します:

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()CAST() などの機能を使用して実行することもできます。 このような場合、式の引数はすべてのリテラルではなくなり、_binary は不要になります。 例:

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

値のタイムスタンプおよびノード番号部分のビットマスクを構築します。 タイムスタンプは最初の 3 つの部分 (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 |
+----------------------------------+

ここでは、マスクが適用される UUID 値と同じ長さである必要があるため、CAST(... AS BINARY(16)) 関数が使用されます。 他の関数を使用して必要な長さまでマスクを埋め込むと、同じ結果が生成されます:

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

前述の例では、これらのビット操作を使用しています: 右シフト (>>) およびビット単位 AND (&)。

注記

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;

all-one アドレスを左または右にシフトして、ネットワークマスクとホストマスクを構築します。 これを行うには、次のようなバイナリ文字列に変換することでわかるように、すべてのゼロの短縮形であるアドレス::から開始します:

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

補完値 (すべて) を生成するには、~ 演算子を使用してビットを反転します:

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

all-one 値を左または右にシフトして、ネットワークマスクとホストマスクを生成します:

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

前述の例では、これらのビット操作を使用しています: 補完 (~)、左シフト (<<) およびビット単位 AND (&)。

残りの説明では、ビット操作の各グループの引数処理、ビット操作でのリテラル値の処理、および MySQL 8.0 と以前の MySQL バージョンとの間の潜在的な非互換性について詳しく説明します。

ビット単位の AND、OR および XOR 操作

&|および ^ ビット操作の場合、結果の型は、引数がバイナリ文字列として評価されるか、数値として評価されるかによって異なります:

  • バイナリ文字列の評価は、引数がバイナリ文字列型で、少なくともそのいずれかが 16 進数リテラル、ビットリテラルまたは NULL リテラルでない場合に発生します。 それ以外の場合は数値の評価が行われ、引数は必要に応じて符号なし 64 ビット整数に変換されます。

  • バイナリ文字列の評価では、引数と同じ長さのバイナリ文字列が生成されます。 引数の長さが等しくない場合は、ER_INVALID_BITWISE_OPERANDS_SIZE エラーが発生します。 数値評価では符号なし 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             |
+---------------+

ビット単位の補完およびシフト操作

~<< および >> ビット操作の場合、結果の型はビット引数がバイナリ文字列として評価されるか、数値として評価されるかによって異なります:

  • バイナリ文字列の評価は、bit 引数がバイナリ文字列型で、16 進数リテラル、ビットリテラルまたは NULL リテラルでない場合に発生します。 それ以外の場合は、必要に応じて引数を符号なし 64 ビット整数に変換することで、数値の評価が行われます。

  • binary-string 評価では、bit 引数と同じ長さのバイナリ文字列が生成されます。 数値評価では符号なし 64 ビット整数が生成されます。

シフト操作では、引数の型に関係なく、値の末尾からシフトされたビットは警告なしで失われます。 特に、シフトカウントが bit 引数のビット数以上の場合、結果のすべてのビットは 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() の操作

BIT_COUNT() 関数は、常に符号なし 64 ビット整数、または引数が NULL の場合は NULL を返します。

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

BIT_AND()、BIT_OR() および BIT_XOR() の操作

BIT_AND()BIT_OR() および BIT_XOR() ビット関数の場合、結果の型は、関数の引数値がバイナリ文字列として評価されるか、数値として評価されるかによって異なります:

  • バイナリ文字列の評価は、引数値がバイナリ文字列型で、引数が 16 進数リテラル、ビットリテラルまたは NULL リテラルでない場合に発生します。 それ以外の場合は数値の評価が行われ、必要に応じて引数値が符号なし 64 ビット整数に変換されます。

  • バイナリ文字列の評価では、引数値と同じ長さのバイナリ文字列が生成されます。 引数値の長さが等しくない場合は、ER_INVALID_BITWISE_OPERANDS_SIZE エラーが発生します。 引数のサイズが 511 バイトを超えると、ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE エラーが発生します。 数値評価では符号なし 64 ビット整数が生成されます。

すべての値が NULL でないかぎり、NULL 値は結果に影響しません。 その場合、結果は引数値の長さと同じ長さの中立値になります (BIT_AND() の場合はすべてのビット 1、BIT_OR() の場合はすべてのビット 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            |
+-----------------+----------------+-----------------+

16 進数リテラル、ビットリテラルおよび NULL リテラルの特殊な処理

下位互換性のため、すべてのビット引数が 16 進数リテラル、ビットリテラルまたは NULL リテラルの場合、MySQL 8.0 は数値コンテキストでビット操作を評価します。 つまり、すべてのビット引数が 16 進数リテラル、ビットリテラルまたは NULL リテラルである場合、バイナリ文字列ビット引数に対するビット操作ではバイナリ文字列評価は使用されません。 (_binary イントロデューサ、BINARY 演算子、またはバイナリ文字列として明示的に指定するその他の方法を使用して記述されている場合、このようなリテラルには適用されません。)

ここで説明したリテラル処理は、MySQL 8.0 の前と同じです。 例:

  • 次のビット操作では、数値コンテキストのリテラルが評価され、BIGINT 結果が生成されます:

    b'0001' | b'0010'
    X'0008' << 8
  • これらのビット操作は、数値コンテキストで NULL を評価し、NULL 値を持つ BIGINT 結果を生成します:

    NULL & NULL
    NULL >> 4

MySQL 8.0 では、少なくとも 1 つの引数がバイナリ文字列であることを明示的に示すことで、これらの操作でバイナリ文字列コンテキストの引数を評価できます:

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

最後の 2 つの式の結果は、BINARY 演算子を使用しない場合と同様に NULL ですが、結果のデータ型は整数型ではなくバイナリ文字列型です。

MySQL 5.7 とのビット操作の非互換性

ビット操作ではバイナリ文字列引数を MySQL 8.0 でネイティブに処理できるため、一部の式では 5.7 とは異なる結果が MySQL 8.0 で生成されます。 監視する問題のある 5 つの式タイプは次のとおりです:

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

これらの式は、8.0 のバイナリ文字列である MySQL 5.7 の BIGINT を返します。

表記法:

  • { op1 op2 ... }: 指定された式タイプに適用される演算子のリスト。

  • binary: 16 進数リテラル、ビットリテラルまたは NULL リテラルを含む任意の種類のバイナリ文字列引数。

  • nonliteral_binary: 16 進数リテラル、ビットリテラルまたは NULL リテラル以外のバイナリ文字列値である引数。

  • AGGR_BIT_FUNC: ビット値引数を取る集計関数: BIT_AND(), BIT_OR(), BIT_XOR()

MySQL 5.7 と 8.0 間の潜在的な非互換性のために MySQL 5.7 で準備する方法の詳細は、MySQL 5.7 Reference ManualBit Functions and Operators を参照してください。

次のリストでは、使用可能なビット関数および演算子について説明します:

  • |

    ビット単位の OR

    結果の型は、引数がバイナリ文字列として評価されるか数値として評価されるかによって異なります:

    • バイナリ文字列の評価は、引数がバイナリ文字列型で、少なくともそのいずれかが 16 進数リテラル、ビットリテラルまたは NULL リテラルでない場合に発生します。 それ以外の場合は数値の評価が行われ、引数は必要に応じて符号なし 64 ビット整数に変換されます。

    • バイナリ文字列の評価では、引数と同じ長さのバイナリ文字列が生成されます。 引数の長さが等しくない場合は、ER_INVALID_BITWISE_OPERANDS_SIZE エラーが発生します。 数値評価では符号なし 64 ビット整数が生成されます。

    詳細は、このセクションの概要の説明を参照してください。

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

    ビット単位の AND

    結果の型は、引数がバイナリ文字列として評価されるか数値として評価されるかによって異なります:

    • バイナリ文字列の評価は、引数がバイナリ文字列型で、少なくともそのいずれかが 16 進数リテラル、ビットリテラルまたは NULL リテラルでない場合に発生します。 それ以外の場合は数値の評価が行われ、引数は必要に応じて符号なし 64 ビット整数に変換されます。

    • バイナリ文字列の評価では、引数と同じ長さのバイナリ文字列が生成されます。 引数の長さが等しくない場合は、ER_INVALID_BITWISE_OPERANDS_SIZE エラーが発生します。 数値評価では符号なし 64 ビット整数が生成されます。

    詳細は、このセクションの概要の説明を参照してください。

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

    ビット単位の XOR

    結果の型は、引数がバイナリ文字列として評価されるか数値として評価されるかによって異なります:

    • バイナリ文字列の評価は、引数がバイナリ文字列型で、少なくともそのいずれかが 16 進数リテラル、ビットリテラルまたは NULL リテラルでない場合に発生します。 それ以外の場合は数値の評価が行われ、引数は必要に応じて符号なし 64 ビット整数に変換されます。

    • バイナリ文字列の評価では、引数と同じ長さのバイナリ文字列が生成されます。 引数の長さが等しくない場合は、ER_INVALID_BITWISE_OPERANDS_SIZE エラーが発生します。 数値評価では符号なし 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'
  • <<

    longlong (BIGINT) 数値またはバイナリ文字列を左にシフトします。

    結果の型は、bit 引数がバイナリ文字列として評価されるか、数値として評価されるかによって異なります:

    • バイナリ文字列の評価は、bit 引数がバイナリ文字列型で、16 進数リテラル、ビットリテラルまたは NULL リテラルでない場合に発生します。 それ以外の場合は、必要に応じて引数を符号なし 64 ビット整数に変換することで、数値の評価が行われます。

    • binary-string 評価では、bit 引数と同じ長さのバイナリ文字列が生成されます。 数値評価では符号なし 64 ビット整数が生成されます。

    値の末尾からシフトされたビットは、引数の型に関係なく、警告なしで失われます。 特に、シフトカウントが bit 引数のビット数以上の場合、結果のすべてのビットは 0 になります。

    詳細は、このセクションの概要の説明を参照してください。

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

    longlong (BIGINT) 数値またはバイナリ文字列を右にシフトします。

    結果の型は、bit 引数がバイナリ文字列として評価されるか、数値として評価されるかによって異なります:

    • バイナリ文字列の評価は、bit 引数がバイナリ文字列型で、16 進数リテラル、ビットリテラルまたは NULL リテラルでない場合に発生します。 それ以外の場合は、必要に応じて引数を符号なし 64 ビット整数に変換することで、数値の評価が行われます。

    • binary-string 評価では、bit 引数と同じ長さのバイナリ文字列が生成されます。 数値評価では符号なし 64 ビット整数が生成されます。

    値の末尾からシフトされたビットは、引数の型に関係なく、警告なしで失われます。 特に、シフトカウントが bit 引数のビット数以上の場合、結果のすべてのビットは 0 になります。

    詳細は、このセクションの概要の説明を参照してください。

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

    すべてのビットを反転します。

    結果の型は、bit 引数がバイナリ文字列として評価されるか、数値として評価されるかによって異なります:

    • バイナリ文字列の評価は、bit 引数がバイナリ文字列型で、16 進数リテラル、ビットリテラルまたは NULL リテラルでない場合に発生します。 それ以外の場合は、必要に応じて引数を符号なし 64 ビット整数に変換することで、数値の評価が行われます。

    • binary-string 評価では、bit 引数と同じ長さのバイナリ文字列が生成されます。 数値評価では符号なし 64 ビット整数が生成されます。

    詳細は、このセクションの概要の説明を参照してください。

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

    引数 N に符号なし 64 ビット整数として設定されているビット数を返します。引数が NULL の場合は NULL を返します。

    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