MySQLでSELECT文を使ってNULL値を置き換える方法の違いとは?IFNULL・COALESCE・CASE文を徹底比較
MySQLでは、SELECT文でNULL値を別の値に置き換える方法がいくつか用意されています。代表的な方法として、IFNULL()関数、COALESCE()関数、そしてCASE文の3つがあります。本記事では、それぞれの構文と実際の出力結果を通じて、各方法の使い方と違いを詳しく解説します。
方法1:IFNULL()関数を使う
IFNULL()は、第1引数がNULLの場合に第2引数で指定した値を返すシンプルな関数です。NULLチェック専用に設計されているため、最も直感的に使えます。
基本構文は以下の通りです。
SELECT IFNULL(カラム名, '置き換える値') AS 別名 FROM テーブル名;
方法2:COALESCE()関数を使う
COALESCE()は、指定した引数の中から最初にNULLではない値を返す関数です。2つ以上の値を渡せる柔軟性があり、標準SQLに準拠している点も特徴です。単純にNULLを置き換える用途では、IFNULL()と同じように使えます。
基本構文は以下の通りです。
SELECT COALESCE(カラム名, '置き換える値') AS 別名 FROM テーブル名;
方法3:CASE文を使う
CASE文は条件分岐を記述できる構文です。NULL以外にも複雑な条件を組み合わせたい場合に有効で、「カラムがNULLなら指定した値を、そうでなければ元の値を返す」というロジックを明示的に書けます。
基本構文は以下の通りです。
SELECT CASE
WHEN カラム名 IS NULL THEN '置き換える値'
ELSE カラム名 END AS 別名 FROM テーブル名
検証用テーブルの作成
それでは、上記3つの方法を実際に試してみましょう。まず、検証用のテーブルを作成します。
mysql> create table ReplaceNULLDemo
-> (
-> Id int NOT NULL AUTO_INCREMENT,
-> Name varchar(10),
-> Marks int,
-> PRIMARY KEY(Id)
-> );
Query OK, 0 rows affected (0.62 sec)
次に、INSERTコマンドでサンプルデータを挿入します。意図的にMarks列にNULLを含むレコードを作成しています。
mysql> insert into ReplaceNULLDemo(Name,Marks) values('Larry',90);
Query OK, 1 row affected (0.16 sec)
mysql> insert into ReplaceNULLDemo(Name,Marks) values('Carol',NULL);
Query OK, 1 row affected (0.17 sec)
mysql> insert into ReplaceNULLDemo(Name,Marks) values('David',NULL);
Query OK, 1 row affected (0.14 sec)
mysql> insert into ReplaceNULLDemo(Name,Marks) values('Bob',67);
Query OK, 1 row affected (0.17 sec)
mysql> insert into ReplaceNULLDemo(Name,Marks) values('Sam',78);
Query OK, 1 row affected (0.19 sec)
mysql> insert into ReplaceNULLDemo(Name,Marks) values('Mike',NULL);
Query OK, 1 row affected (0.19 sec)
mysql> insert into ReplaceNULLDemo(Name,Marks) values('John',98);
Query OK, 1 row affected (0.16 sec)SELECT文ですべてのレコードを表示してみます。
mysql> select *from ReplaceNULLDemo;
出力結果は以下の通りです。
+----+-------+-------+
| Id | Name | Marks |
+----+-------+-------+
| 1 | Larry | 90 |
| 2 | Carol | NULL |
| 3 | David | NULL |
| 4 | Bob | 67 |
| 5 | Sam | 78 |
| 6 | Mike | NULL |
| 7 | John | 98 |
+----+-------+-------+
7 rows in set (0.00 sec)
Marks列にはNULLが3件含まれています。以降では、このNULLを0に置き換えてみます。
実践1:IFNULL()でNULLを0に置き換える
クエリは以下の通りです。
mysql> select ifnull(Marks,0) as ReplacementOfNULLWith0 from ReplaceNULLDemo;
NULLが0に置き換えられて出力されます。
+------------------------+
| ReplacementOfNULLWith0 |
+------------------------+
| 90 |
| 0 |
| 0 |
| 67 |
| 78 |
| 0 |
| 98 |
+------------------------+
7 rows in set (0.00 sec)
実践2:COALESCE()でNULLを0に置き換える
クエリは以下の通りです。
mysql> select coalesce(Marks,0) as ReplacementOfNULLWith0 from ReplaceNULLDemo;
出力結果を見ると、IFNULL()とまったく同じ結果が得られていることがわかります。
+------------------------+
| ReplacementOfNULLWith0 |
+------------------------+
| 90 |
| 0 |
| 0 |
| 67 |
| 78 |
| 0 |
| 98 |
+------------------------+
7 rows in set (0.00 sec)
実践3:CASE文でNULLを0に置き換える
クエリは以下の通りです。
mysql> select case
-> when Marks is null then 0
-> else Marks end as ReplacementOfNULLWith0
-> from ReplaceNULLDemo;
こちらも同様に、NULLが0に置き換えられて出力されます。
+------------------------+
| ReplacementOfNULLWith0 |
+------------------------+
| 90 |
| 0 |
| 0 |
| 67 |
| 78 |
| 0 |
| 98 |
+------------------------+
7 rows in set (0.00 sec)
まとめ:どの方法を選ぶべきか?
3つの方法はすべて同じ結果を返しますが、使い分けのポイントがあります。
- IFNULL():MySQL独自の関数で、NULLかどうかの2択判定に特化。シンプルで可読性が高い。
- COALESCE():標準SQL準拠のため、他のデータベースへの移植性を重視する場合に最適。複数の候補値から最初の非NULL値を取得できる。
- CASE文:NULL以外の複雑な条件分岐も同じクエリ内で扱いたい場合に有効。
単純にNULLを置き換えるだけならIFNULL()またはCOALESCE()で十分ですが、将来的な移植性や複雑な条件が必要になる可能性を考慮すると、COALESCE()やCASE文を選ぶのも良い選択肢です。
-
MySQLの同じSELECTステートメント内でエイリアスの値を参照する方法
MySQLでは、SELECT句内で定義したエイリアス(別名)を、同じステートメント内の他のカラムや式から直接参照することはできません。これはSQLの仕様上、SELECT句の評価順序に関係する制限です。 しかし、この制限を回避する方法があります。それがユーザー定義変数です。変数に値を代入しながらエイリアスとして出力すれば、同じクエリ内でもその値を再利用できます。 基本構文 以下がユーザー定義変数を使った基本構文です。ここで @yourAliasName はユーザー定義変数、anyAliasName は任意のエイリアス名を表します。 select @yourAliasName := curdate
-
MySQLにおける「!=NULL」と「IS NOT NULL」の違いとは?
MySQLでは、値を!=NULLと比較すると、結果は必ずNULLになります。つまり、!=NULLという比較は意味を持ちません。NULLは「不明な値」を表すため、通常の比較演算子では判定できないのです。NULL値を判定するには、専用の演算子であるIS NOT NULLを使用します。ここでは、!=NULLとIS NOT NULLの違いを実際に確認するために、まずテーブルを作成します。テーブルの作成まず、次のコマンドでテーブルを作成します。mysql> create table DemoTable1970 (