- MySQL
- 2022-10-11
今回はMySQLでのNULL安全等価演算子についてご紹介します。
NULL安全等価演算子とは<=>
のことで、見た目が宇宙船に似ていることからSpaceship Operator(宇宙船演算子)とも言われます。
※他言語でもあるんですが、返り値が違ったりするのでご注意ください。
まず、値の比較について見ていきます。
1
と1
を等価演算子で比較します。
MySQL> SELECT 1 = 1; +-------+ | 1 = 1 | +-------+ | 1 | +-------+
結果は真の1
となりました。
次は1
と0
を比較してみましょう。
MySQL> SELECT 1 = 0; +-------+ | 1 = 0 | +-------+ | 0 | +-------+
結果は偽の0
となりました。
今後は1
とNULL
を比較してみます。
MySQL> SELECT 1 = NULL; +----------+ | 1 = NULL | +----------+ | NULL | +----------+
結果は偽の0
となるかと思いきや、NULL
となりました。
NULL
同士を比較するとどうでしょうか。
MySQL> SELECT NULL = NULL; +-------------+ | NULL = NULL | +-------------+ | NULL | +-------------+
結果はNULL
となりました。
1
とNULL
の場合は0
、NULL
同士の場合は1
になって欲しいですよね。
そこで登場するのが、今回のNULL安全等価演算子(宇宙船演算子)です。
それを使うと次のようになります。
1
とNULL
の場合
SELECT 1 <=> NULL; +------------+ | 1 <=> NULL | +------------+ | 0 | +------------+
NULL
同士の場合
SELECT NULL <=> NULL; +---------------+ | NULL <=> NULL | +---------------+ | 1 | +---------------+
ということで、まさに欲しい結果が返ってきてくれます。
続いてサンプルデータを用いて、実際の事例をご紹介します。
ここで例えば、2つのテーブルからデータを抽出するSQLを組むと仮定しましょう。
例として次のような適当なサンプルデータを用意しました。
mysql> SELECT * FROM sampleA; +----+--------+------+ | id | name | type | +----+--------+------+ | 1 | 赤井 | 1 | | 2 | 井田 | 2 | | 3 | 宇野 | NULL | | 4 | 江崎 | 1 | | 5 | 奥本 | 2 | +----+--------+------+ mysql> SELECT * FROM sampleB; +----+--------+------+ | id | name | type | +----+--------+------+ | 1 | 赤井 | 1 | | 2 | 井田 | 2 | | 3 | 宇野 | NULL | | 4 | 江崎 | 1 | | 5 | 奥本 | 2 | +----+--------+------+
sampleA
とsampleB
は全く同じ内容です。
ここで、sampleA
とsampleB
のname
とtype
を結び付けてデータを抽出してみます。
SELECT * FROM sampleA -> INNER JOIN sampleB -> ON sampleA.name = sampleB.name -> AND sampleA.type = sampleB.type; +----+------+------+----+------+------+ | id | name | type | id | name | type | +----+------+------+----+------+------+ | 1 | 赤井 | 1 | 1 | 赤井 | 1 | | 2 | 井田 | 2 | 2 | 井田 | 2 | | 4 | 江崎 | 1 | 4 | 江崎 | 1 | | 5 | 奥本 | 2 | 5 | 奥本 | 2 | +----+------+------+----+------+------+
そうすると、結果にtype
がNULL
のデータは含まれていません。
type
がNULL
のデータも含んで欲しい場合は次のようにします。
SELECT * FROM sampleA -> INNER JOIN sampleB -> ON sampleA.name = sampleB.name -> AND (sampleA.type = sampleB.type OR (sampleA.type IS NULL AND sampleB.type IS NULL)); +----+------+------+----+------+------+ | id | name | type | id | name | type | +----+------+------+----+------+------+ | 1 | 赤井 | 1 | 1 | 赤井 | 1 | | 2 | 井田 | 2 | 2 | 井田 | 2 | | 3 | 宇野 | NULL | 3 | 宇野 | NULL | | 4 | 江崎 | 1 | 4 | 江崎 | 1 | | 5 | 奥本 | 2 | 5 | 奥本 | 2 | +----+------+------+----+------+------+
NULL
のデータも表示されました。
これをNULL安全等価演算子(宇宙船演算子)を使って抽出してみます。
SELECT * FROM sampleA -> INNER JOIN sampleB -> ON sampleA.name = sampleB.name -> AND sampleA.type <=> sampleB.type; +----+------+------+----+------+------+ | id | name | type | id | name | type | +----+------+------+----+------+------+ | 1 | 赤井 | 1 | 1 | 赤井 | 1 | | 2 | 井田 | 2 | 2 | 井田 | 2 | | 3 | 宇野 | NULL | 3 | 宇野 | NULL | | 4 | 江崎 | 1 | 4 | 江崎 | 1 | | 5 | 奥本 | 2 | 5 | 奥本 | 2 | +----+------+------+----+------+------+
いかがでしょうか。
SQL文が少しスッキリしていますよね。
皆さんにも是非活用していただければと思います。