皆さんはカラムにNULLが入らないようにするNOT NULL制約を積極的に使っていますか? もし使うにしても、
今回は、
検証環境
今回は第125回 phpMyAdminでDockerで建てたMySQLにアクセスするで記載したdocker-composeを利用して作成します。手元で簡単に試せるように、
NULL値の比較に関して
まずはNULL値の比較を始める前に、
mysql> select 1 = 1; +-------+ | 1 = 1 | +-------+ | 1 | +-------+ 1 row in set (0.00 sec)
結果は1が帰ってきました。1と1を比較して真になりました。続いて1と0を比較して結果が偽になる場合を試してみます。
mysql> select 1 = 0; +-------+ | 1 = 0 | +-------+ | 0 | +-------+ 1 row in set (0.00 sec)
結果は0なので、
mysql> select 1 = NULL; +----------+ | 1 = NULL | +----------+ | NULL | +----------+ 1 row in set (0.00 sec)
結果がNULLになりました。
続いて、
mysql> select NULL = NULL; +-------------+ | NULL = NULL | +-------------+ | NULL | +-------------+ 1 row in set (0.00 sec)
結果は真になるかと思いきや、IS NULL
を使用する必要があります。
mysql> SELECT NULL IS NULL; +--------------+ | NULL IS NULL | +--------------+ | 1 | +--------------+ 1 row in set (0.00 sec)
NULL同士の比較をする場合には注意が必要です。
ちょっと脇道にそれてしまうのですが、SELECT NULL = NULL IS NULL;
を実行すると結果が何になるかわかるでしょうか? こちらは試してみるとすぐにわかって、
mysql> select NULL = NULL IS NULL; +---------------------+ | NULL = NULL IS NULL | +---------------------+ | 1 | +---------------------+ 1 row in set (0.00 sec)
このように、
INTERVAL
BINARY, COLLATE
!
- (unary minus), ~ (unary bit inversion)
^
*, /, DIV, %, MOD
-, +
<<, >>
&
|
= (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN, MEMBER OF
BETWEEN, CASE, WHEN, THEN, ELSE
NOT
AND, &&
XOR
OR, ||
= (assignment), :=
上記はドキュメントから抜粋した演算子の優先順位で、=(comparison)
とIS
で同じ行にありますが、=(comparison)
のほうが先に評価されて、IS
が評価されていることがわかります。
<=>演算子を使ってみる
<=>演算子は見た目が非常に宇宙船に似ている事から、
ここでは、
1と1を比較した場合と、
mysql> select 1 <=> 1 , 1 <=> 0; +---------+---------+ | 1 <=> 1 | 1 <=> 0 | +---------+---------+ | 1 | 0 | +---------+---------+ 1 row in set (0.00 sec)
上記は、,
でつないで一度に出力することができます。では続いて1とNULLの比較を行ってみましょう。
mysql> select 1 <=> NULL; +------------+ | 1 <=> NULL | +------------+ | 0 | +------------+ 1 row in set (0.00 sec)
結果がNULLではなくて、
mysql> select NULL <=> NULL; +---------------+ | NULL <=> NULL | +---------------+ | 1 | +---------------+ 1 row in set (0.00 sec)
結果が通常の=
での比較と結果が変わって、IS NULL
と同じような挙動をしてくれる機能になります。
こちらは非常に便利な演算子です。特に最近では自作することはあまりないと思いますが、
IS NOT NULL
を表すにはどうしたら良いのか?
mysql> SELECT NOT( 1 <=> NULL), NOT( NULL <=> NULL); +------------------+---------------------+ | NOT( 1 <=> NULL) | NOT( NULL <=> NULL) | +------------------+---------------------+ | 1 | 0 | +------------------+---------------------+ 1 row in set (0.00 sec)
ただし、
まとめ
今回はMySQLの固有の機能である<=>演算子について紹介しました。<=>演算子を使うと、
特にNULLが来るかどうかよくわからない値のプレースホルダーと組み合わせて使用すると、
ただ、