0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【MySQL】NULL 安全等価比較演算子 <=> を解説

0
Posted at

SQL における NULL の扱いは多くの開発者を悩ませるポイントです。

特に、次のような比較がうまく動かない経験は誰でもあると思います。

SELECT * FROM users WHERE name = NULL;   -- 取れない
SELECT * FROM users WHERE name <> NULL;  -- 取れない

これは、SQL 標準仕様で
NULL を比較演算子(= や <>)で評価すると、結果が必ず NULL(UNKNOWN)になる
というルールがあるためです。

🔥 MySQL 独自の NULL 安全比較 <=> とは?

MySQL には、他の主要 RDBMS には存在しない特別な演算子<=>が存在します。
これは NULL セーフ等価比較(NULL-safe equal) と呼ばれます。

NULL を含む比較であっても TRUE / FALSE を返す、MySQL 独自の比較演算子と理解すれば OK です。

✔ 動作仕様

結果
1 <=> 1 TRUE
1 <=> 2 FALSE
1 <=> NULL FALSE
NULL <=> NULL TRUE

通常の = と最も異なる点はここ:

NULL <=> NULL が TRUE になる。

SQL 標準では NULL = NULL は UNKNOWN(NULL)。
しかし <=> は「両方 NULL のときは等しい」と判断します。

🔎 例:通常の比較との違いを確認する

以下は MySQL のテーブル例と比較結果です。

CREATE TABLE samples (
  id INT,
  val INT
);

INSERT INTO samples VALUES
  (1, 100),
  (2, NULL),
  (3, 100),
  (4, NULL);

■ = を使う場合(NULL は比較できない)

SELECT * FROM samples WHERE val = NULL;

→ 1 行も返らない

理由:val = NULL は常に NULL(UNKNOWN)になり、WHERE では除外されるため。

■ <=> を使う場合(NULL も比較できる)

SELECT * FROM samples WHERE val <=> NULL;

→ val に NULL の行が返る

id | val
-----------
2  | NULL
4  | NULL

🎯 典型的なユースケース

1. NULL を含む「等価検索」を行いたい時

-- val が NULL の行も含めて比較したい
SELECT * FROM samples
WHERE val <=> :value;

アプリケーションから検索値に NULL が渡されても、
WHERE val <=> NULL
として正しく動作します。

2. 「値が変化したかどうか」を比較したい時

例えば、UPDATE による変更判定。

-- 値が変化した行だけ更新
UPDATE users
SET updated_at = NOW()
WHERE NOT (users.value <=> :new_value);

<=> を使うことで、
NULL から値ありへの変更
値ありから NULL への変更
も確実に検知できる。

3. 一意性チェック(NULL を含む場合)

通常の = では NULL 同士が比較できないため、
アプリ側で NULL を意識した分岐が必要になる場面があります。

SELECT 1 FROM items
WHERE unique_key <=> :key_value;

NULL を含む一意チェックを簡潔に書けます。

🚨 注意点:SQL 標準ではない(MySQL / MariaDB 限定)

重要なポイント:

<=> は MySQL および MariaDB の独自仕様

PostgreSQL / SQL Server / Oracle / SQLite には存在しない

他の RDBMS に移植する可能性のあるアプリケーションでは使用を検討する必要があります。

(ただし、NULL の扱いを厳密にしたい場面では非常に便利で、
MySQL でしか動かないデメリット以上に、メリットが大きいことも多い。)

✔ まとめ

SQL 標準の = では NULL を比較できないため、比較したい場合は安全等価比較 <=> を使用する

<=> は NULL 同士の比較でも TRUE を返す

検索、変更検知、一意性チェックなどで非常に便利

<=> は MySQL / MariaDB 限定の機能なので移植には注意

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?