技術資料

MySQLのCASE式入門:条件に応じてSELECTの出力を切り替える

作成日:2026.10.12

MySQLのCASE式を使い、条件に応じてSELECTの出力値を切り替える方法を解説します。状態コードを表示名に変換する例を通して、基本構文、ELSEとNULLの扱い、条件が重なる場合のWHENの順序を紹介します。

SELECTで状態コードを取得したとき、0や1のままでは意味が分かりにくいことがあります。そんなときは、CASE式を使うと、条件に応じて「未完了」「完了」などの表示名を返せます。

今回は、MySQLのCASE式の基本と、条件の順序、ELSE、NULLの扱いを説明します。SELECTの基本が分かる人向けの内容です。

対象はMySQL 8.4です。仕様は2026年10月12日時点の公式資料で確認しています。日本語の例は、UTF-8のSQLを送受信できるクライアントと、utf8mb4の接続を前提にします。

CASE WHENで条件に応じた値を返す

基本的な形は次のとおりです。ここでは、構文の各部分を日本語で示しています。

CASE
    WHEN 条件1 THEN 条件1を満たすときの値
    WHEN 条件2 THEN 条件2を満たすときの値
    ELSE どの条件も満たさないときの値
END

WHENの後に条件、THENの後に返す値を書きます。条件は上から確認され、最初に成立した条件の値が採用されます。どの条件も成立しなければ、ELSEの値を返します。

例えば、次のSELECTでは、1 = 1が成立するので、status_nameの期待結果は「完了」です。

SELECT
    CASE
        WHEN 1 = 1 THEN '完了'
        ELSE '未完了'
    END AS status_name;

CASE式全体が一つの値を返し、AS status_nameでその列に名前を付けています。ENDはCASE式の終わりで、SQL文の終わりを表すセミコロンは、その後に置きます。構文の詳細は、MySQL公式のCASE式の説明を参照してください。

なお、ストアドプログラム内で処理を分岐するCASE文には、END CASEで終わる別の構文があります。今回は、SELECTの中で値を返すCASE式を扱います。

状態コードから表示名を作る

今度は、元の状態コードと表示名を並べてみます。説明用の注文状態として、0を未完了、1を完了とします。想定外のコードと、値が入っていないNULLも含めます。

WITH sample_orders AS (
    SELECT 1 AS id, 0 AS status
    UNION ALL SELECT 2, 1
    UNION ALL SELECT 3, 9
    UNION ALL SELECT 4, NULL
)
SELECT
    id,
    status,
    CASE
        WHEN status IS NULL THEN '未設定'
        WHEN status = 0 THEN '未完了'
        WHEN status = 1 THEN '完了'
        ELSE '未定義'
    END AS status_name
FROM sample_orders
ORDER BY id;

WITH句の中では、比較用の4行を作っています。テーブルを作成したり、保存済みのデータを変更したりする必要はありません。WITH句の使い方は、MySQLのWITH句入門の記事で説明しています。

idstatusstatus_name
10未完了
21完了
39未定義
4NULL未設定

この例では、コード9はどのWHENにも該当しないのでELSEへ進みます。NULLは最初のstatus IS NULLに該当するため、「未設定」になります。

NULLを調べるときは、status = NULLではなくstatus IS NULLを使います。= NULLによる比較は真にならず、WHENの条件として成立しません。NULLは0や空文字とも区別します。詳しくは、MySQL公式のNULL値の扱いを参照してください。

「未設定」「未定義」という表示は、この例で決めたものです。実際には、NULLと想定外のコードを同じ扱いにするか、別表示にするかを、用途に合わせて決めましょう。返す値は、今回のように表示名なら文字列へそろえておくと分かりやすいです。CASE式の結果の型は、THENとELSEに書いた値の型の組み合わせで決まります。

また、ここで変わるのは出力する列の値です。CASE式を書くだけで行が除かれるわけではありません。取得する行を絞りたい場合は、WHEREの条件で指定します。

値の一致だけなら、CASEの後に比較する値を書ける

同じ値を複数の候補と比較するだけなら、CASE 値 WHEN 比較値 THEN ... ENDという形でも書けます。

SELECT
    CASE 1
        WHEN 0 THEN '未完了'
        WHEN 1 THEN '完了'
        ELSE '未定義'
    END AS status_name;

この例の期待結果も「完了」です。列を使うなら、CASE status WHEN 0 THEN ...のように書きます。ただし、WHEN NULLと書いてもNULLの判定にはなりません。先ほどの例のようにIS NULLや大小比較などの条件を使いたい場合は、CASE WHEN 条件 THEN ...の形が適しています。

ELSEを省略すると、該当しない値はNULLになる

ELSEは省略できますが、その場合、どの条件にも該当しないときはNULLを返します。次の例では、ELSEあり・なしの違いを比べています。

SELECT
    CASE
        WHEN 9 = 0 THEN '未完了'
        WHEN 9 = 1 THEN '完了'
    END AS without_else,
    CASE
        WHEN 9 = 0 THEN '未完了'
        WHEN 9 = 1 THEN '完了'
        ELSE '未定義'
    END AS with_else;
without_elsewith_else
NULL未定義

入力がNULLでも、status = 0やstatus = 1は成立しません。NULL専用の条件もELSEもなければ、結果はNULLになります。表示名を必ず返したい場合は、NULLを扱う条件とELSEを含めて、想定外の値の扱いを決めておきましょう。

条件が重なるときは、WHENの順序に注意する

CASE式は、成立した条件の中から、自動的に「より細かい条件」を選ぶわけではありません。金額に応じた分類を例に、WHENの順序を比べてみます。

WITH sample_amounts AS (
    SELECT 0 AS amount
    UNION ALL SELECT 1000
    UNION ALL SELECT 5000
)
SELECT
    amount,
    CASE
        WHEN amount >= 1000 THEN '1000円以上'
        WHEN amount >= 5000 THEN '5000円以上'
        ELSE '1000円未満'
    END AS broad_first,
    CASE
        WHEN amount >= 5000 THEN '5000円以上'
        WHEN amount >= 1000 THEN '1000円以上'
        ELSE '1000円未満'
    END AS narrow_first
FROM sample_amounts
ORDER BY amount;
amountbroad_firstnarrow_first
01000円未満1000円未満
10001000円以上1000円以上
50001000円以上5000円以上

5000円は、amount >= 1000にも該当します。そのため、broad_firstでは最初のWHENが採用され、「1000円以上」になります。5000円以上を別の分類にしたいなら、narrow_firstのように、その条件を先に書きます。

条件を追加したときは、その条件が既存のWHENに先に拾われないか、境界の値も含めて確認しておくとよいかと思います。

CASE式を使うと、元の値を残したまま、条件に応じた表示名や分類を追加できます。まずは元の列とCASE式の結果を並べて、通常の値だけでなく、NULL、想定外の値、条件の境界でどう出力されるかを確認してみてください。

この記事を書いた人

※上が私です。

奈良市を拠点に、27年以上の経験を持つフリーランスWebエンジニア、阿部辰也です。

これまで、ECサイトのバックエンド開発や業務効率化システム、公共施設の予約システムなど、多彩なプロジェクトを手がけ、企業様や制作会社様のパートナーとして信頼を築いてまいりました。

【制作会社・企業様向けサポート】
  • 専任エンジニアのいない企業様に対するシステム面の不安を解消
  • 柔軟な契約形態や短納期での対応により、急なニーズにも迅速にサポート
  • システムの企画段階から運用まで、ワンストップでのサービスを提供

Webシステムの開発やサイト改善でお困りの際は、どうぞお気軽にご相談ください。小さな疑問から大規模プロジェクトまで、最適なご提案を心を込めてさせていただきます。

ぜひ、プロフィールやWeb制作会社様向け業務案内、一般企業様向け業務案内もご覧くださいね。

MySQLのDATE_FORMATとTIME_TO_SEC:日時の表示と時間の数値化

2026.10.13

MySQLのDATE_FORMATで日時の表示を整える方法と、TIME_TO_SECで時間を秒数へ変換する方法を解説します。入力と結果を比較しながら、月と分の書式指定、NULL、負の時間、24時間を超える時間の扱いも紹介します。

MySQL

MySQLで文字列を整形・抽出する:TRIM・SUBSTRING_INDEX・REGEXP_SUBSTRの使い方

2026.10.11

MySQLで取得する文字列から不要な空白を除いたり、区切り文字や正規表現を使って必要な部分を取り出したりする方法を紹介します。TRIM・SUBSTRING_INDEX・REGEXP_SUBSTRの基本構文と使い分けを、具体的なSQL例で解説。NULLや空文字、想定した形式に合わない値を扱う際の注意点も整理します。

MySQL

phpMyAdminユーザー向けMySQL Workbench入門:テーブル確認からSQL実行まで

2026.10.10

phpMyAdminに慣れた人向けに、MySQL Workbenchの基本操作を解説します。両ツールの動作場所と接続経路の違いから、接続設定、テーブル・カラムの構造確認、SQLの実行、結果とエラーの見方までを紹介。SELECTを試す前にEXPLAINで実行計画を確認する手順も扱います。

MySQL MySQL Workbench phpMyAdmin

MySQLのWITH句入門:SELECTの結果を加工・集計する方法

2026.10.09

MySQLのWITH句を使って、SELECTの取得結果を加工・集計する方法を解説します。注文データを例に、CTE(共通テーブル式)の基本と複数CTEの書き方、サブクエリとの違い、利用時の注意点を紹介します。

MySQL

阿部辰也へのお仕事の依頼・お問い合わせ

軽いご相談もお気軽にどうぞ!

個人情報の取り扱いについて *必須 プライバシーポリシーをご確認いただき、同意いただける場合は「同意する」にチェックをしてください。

keyboard_double_arrow_up
TOP