MySQLのCASE句とは?Javaのswitch文と比較して新人エンジニア向けにやさしく解説
こんにちは。ゆうせいです。
今回は、MySQLのCASE句について、Javaのswitch文と比較しながら新人エンジニア向けに解説します。
CASE句は、SQLの中で条件分岐を行うための書き方です。
Javaで条件分岐といえば、if文やswitch文を思い浮かべる人が多いと思います。
MySQLのCASEも、考え方としてはそれに近いです。
ただし、MySQLのCASEは「処理の流れを変える」というより、「条件に応じて返す値を変える」ために使うことが多いです。
たとえるなら、Javaのswitch文は「行き先を分ける案内係」です。
一方で、MySQLのCASE句は「条件に応じて表示ラベルを貼り替える係」です。
同じ分岐でも、使う場所と目的が少し違います。
MySQLのCASE句とは何か
MySQLのCASE句とは、SQLの中で「もし条件Aなら値A、条件Bなら値B、それ以外なら値C」のように、条件によって返す値を変えるための仕組みです。
MySQL公式ドキュメントでは、CASE演算子には2つの構文があり、条件が真になった最初の結果を返し、どれにも当てはまらない場合はELSEの結果、ELSEがなければNULLを返すと説明されています。なお、ストアドプログラム内で使うCASE文とは構文が少し異なります。
まずは、基本形を見てみましょう。
SELECT
car_id,
name,
price,
CASE
WHEN price >= 3000000 THEN '高価格'
WHEN price >= 1500000 THEN '中価格'
ELSE '低価格'
END AS price_rank
FROM cars;このSQLは、車の価格に応じて、price_rankという表示用の分類を作っています。
| priceの値 | CASEの結果 |
|---|---|
| 3000000以上 | 高価格 |
| 1500000以上3000000未満 | 中価格 |
| 1500000未満 | 低価格 |
ポイントは、carsテーブルにprice_rankというカラムがなくても、SELECT結果の中で一時的に分類を作れることです。
学校の成績でたとえるなら、点数カラムだけがある状態から、CASEを使って「A評価」「B評価」「C評価」というラベルを付けるようなものです。
CASE句の2つの書き方
MySQLのCASEには、大きく2つの書き方があります。
| 種類 | 特徴 | Javaで近いもの |
|---|---|---|
| 単純CASE | 1つの値を複数の候補と比較する | switch文に近い |
| 検索CASE | WHENごとに自由な条件を書く | if、else ifに近い |
新人エンジニアは、まずこの2つを分けて覚えると理解しやすいです。
単純CASE:Javaのswitch文に近い書き方
単純CASEは、1つの値を見て、どの値に一致するかで結果を変える書き方です。
SELECT
car_id,
name,
status,
CASE status
WHEN 1 THEN '販売中'
WHEN 2 THEN '売約済み'
WHEN 3 THEN '販売停止'
ELSE '不明'
END AS status_name
FROM cars;このCASEでは、statusの値を見ています。
| status | status_name |
|---|---|
| 1 | 販売中 |
| 2 | 売約済み |
| 3 | 販売停止 |
| それ以外 | 不明 |
Javaのswitch文で書くと、考え方は次のようになります。
String statusName;
switch (status) {
case 1:
statusName = "販売中";
break;
case 2:
statusName = "売約済み";
break;
case 3:
statusName = "販売停止";
break;
default:
statusName = "不明";
break;
}かなり似ていますよね。
どちらも「statusの値が1なら販売中、2なら売約済み、3なら販売停止」という分岐をしています。
ただし、MySQLのCASEはSQLの中で値を返すために使っています。
Javaのswitch文は、Javaプログラムの中で処理を分岐させるために使っています。
検索CASE:Javaのif、else ifに近い書き方
検索CASEは、WHENごとに条件式を書けるCASEです。
価格帯のように、「300万円以上」「150万円以上」のような範囲判定をしたい場合に使いやすいです。
SELECT
car_id,
name,
price,
CASE
WHEN price >= 3000000 THEN '高価格'
WHEN price >= 1500000 THEN '中価格'
ELSE '低価格'
END AS price_rank
FROM cars;Javaのif文で書くと、次のようなイメージです。
String priceRank;
if (price >= 3000000) {
priceRank = "高価格";
} else if (price >= 1500000) {
priceRank = "中価格";
} else {
priceRank = "低価格";
}検索CASEは、Javaのswitch文よりもif、else ifに近いです。
なぜなら、WHENの中に自由な条件を書けるからです。
| 書き方 | 向いている条件 |
|---|---|
| 単純CASE | status = 1、status = 2 のような一致判定 |
| 検索CASE | price >= 3000000 のような範囲判定 |
迷ったら、まず検索CASEを使うと柔軟に書けます。
Javaのswitch文との大きな違い
MySQLのCASE句とJavaのswitch文は似ていますが、かなり重要な違いがあります。
| 比較 | MySQLのCASE句 | Javaのswitch文 |
|---|---|---|
| 使う場所 | SQLの中 | Javaプログラムの中 |
| 主な目的 | 条件に応じて値を返す | 条件に応じて処理を分岐する |
| 返すもの | 値 | 処理の流れ、またはswitch式なら値 |
| よく使う場面 | SELECT、ORDER BY、集計 | 業務ロジック、画面制御、処理分岐 |
| 終了の書き方 | END | breakやreturnなど |
| デフォルト | ELSE | default |
特に大事なのは、「MySQLのCASEは値を返す」という点です。
Javaのswitch文は、何かの処理を実行するために使うことが多いです。
一方で、MySQLのCASEは、SELECT結果の1列として値を作るために使うことが多いです。
CASE句はSELECTの中でよく使う
CASE句の一番よくある使い方は、SELECT句の中で表示用の値を作る方法です。
たとえば、carsテーブルに次のようなデータがあるとします。
| car_id | name | price | deleted_at |
|---|---|---|---|
| 1 | プリウス | 2500000 | NULL |
| 2 | 高級SUV | 4500000 | NULL |
| 3 | 軽自動車 | 1200000 | NULL |
| 4 | 旧モデル | 800000 | 2026-01-01 10:00:00 |
このデータに対して、価格ランクを表示したい場合です。
SELECT
car_id,
name,
price,
CASE
WHEN price >= 3000000 THEN '高価格'
WHEN price >= 1500000 THEN '中価格'
ELSE '低価格'
END AS price_rank
FROM cars;結果は次のようなイメージになります。
| car_id | name | price | price_rank |
|---|---|---|---|
| 1 | プリウス | 2500000 | 中価格 |
| 2 | 高級SUV | 4500000 | 高価格 |
| 3 | 軽自動車 | 1200000 | 低価格 |
| 4 | 旧モデル | 800000 | 低価格 |
price_rankは、テーブルに保存されているカラムではありません。
SELECTするときにCASEで作った一時的な表示用の値です。
レストランでたとえるなら、料理そのものは同じでも、メニュー表で「おすすめ」「激辛」「低カロリー」のラベルを付けるようなものです。
CASE句で論理削除の状態を表示する
deleted_atを使った論理削除でも、CASE句はよく使えます。
論理削除とは、DELETEで物理的に消すのではなく、deleted_atに日時を入れて削除済み扱いにする方法です。
deleted_atがNULLなら有効データ、NULLでなければ削除済みデータと考えます。
SELECT
car_id,
name,
price,
deleted_at,
CASE
WHEN deleted_at IS NULL THEN '有効'
ELSE '削除済み'
END AS delete_status
FROM cars;このSQLでは、deleted_atの状態に応じて、有効または削除済みを表示しています。
| deleted_at | delete_status |
|---|---|
| NULL | 有効 |
| 日時あり | 削除済み |
Javaで書くなら、次のようなif文のイメージです。
String deleteStatus;
if (deletedAt == null) {
deleteStatus = "有効";
} else {
deleteStatus = "削除済み";
}ここはJavaのswitch文よりif文に近いですね。
NULL判定や範囲判定では、検索CASEが便利です。
CASE句はORDER BYでも使える
CASE句は、SELECT句だけでなくORDER BYでも使えます。
ORDER BYは、検索結果を並び替えるための句です。
たとえば、車を「販売中を先に、販売停止を後に」並べたい場合があります。
SELECT
car_id,
name,
status
FROM cars
ORDER BY
CASE status
WHEN 1 THEN 1
WHEN 2 THEN 2
WHEN 3 THEN 3
ELSE 9
END;このSQLでは、statusの値を並び替え用の数字に変換しています。
| status | 並び替え用の値 | 意味 |
|---|---|---|
| 1 | 1 | 販売中 |
| 2 | 2 | 売約済み |
| 3 | 3 | 販売停止 |
| その他 | 9 | 最後に回す |
Javaでソート条件を作るのに近い考え方です。
ただし、SQL側で並び順を作っているので、DBから取得した時点で並び替え済みになります。
画面側やJava側で並び替えるより、SQLで済むならSQLで行うほうがシンプルな場面もあります。
CASE句は集計でも使える
CASE句は、集計と組み合わせるとかなり便利です。
たとえば、carsテーブルの中で、高価格、中価格、低価格の件数を数えたいとします。
SELECT
CASE
WHEN price >= 3000000 THEN '高価格'
WHEN price >= 1500000 THEN '中価格'
ELSE '低価格'
END AS price_rank,
COUNT(*) AS car_count
FROM cars
WHERE deleted_at IS NULL
GROUP BY
CASE
WHEN price >= 3000000 THEN '高価格'
WHEN price >= 1500000 THEN '中価格'
ELSE '低価格'
END;結果は次のようなイメージです。
| price_rank | car_count |
|---|---|
| 高価格 | 5 |
| 中価格 | 12 |
| 低価格 | 8 |
このように、CASEを使うと、テーブルにprice_rankというカラムがなくても、価格帯ごとの集計ができます。
これはとても実務的です。
売上分析、在庫分析、ユーザー分類、ログ分析などでよく使われます。
SUMとCASEを組み合わせる
さらに、SUMとCASEを組み合わせると、条件に合う件数を横並びで集計できます。
SELECT
SUM(CASE WHEN price >= 3000000 THEN 1 ELSE 0 END) AS high_price_count,
SUM(CASE WHEN price >= 1500000 AND price < 3000000 THEN 1 ELSE 0 END) AS middle_price_count,
SUM(CASE WHEN price < 1500000 THEN 1 ELSE 0 END) AS low_price_count
FROM cars
WHERE deleted_at IS NULL;このSQLは、価格帯ごとの件数を1行で返します。
| high_price_count | middle_price_count | low_price_count |
|---|---|---|
| 5 | 12 | 8 |
CASEの中で、条件に合う場合は1、合わない場合は0を返しています。
その1と0をSUMで合計することで、条件に合う件数を数えています。
記号の式で表すと、次のようなイメージです。
count = sum(1 if condition else 0)
日本語に置き換えると、次の意味です。
件数 = 合計(条件に合えば1、それ以外なら0)
これは、出席を数えるイメージに近いです。
出席している人を1、欠席している人を0として合計すると、出席人数が出ますよね。
CASEとSUMの組み合わせも同じです。
CASE句の判定順序に注意する
CASE句では、WHENは上から順番に判定されます。
最初に条件を満たしたTHENが採用されます。
MySQL公式ドキュメントでも、CASE演算子は最初に真になった条件の結果を返すと説明されています。
ここはとても重要です。
悪い例を見てみましょう。
SELECT
name,
price,
CASE
WHEN price >= 1500000 THEN '中価格'
WHEN price >= 3000000 THEN '高価格'
ELSE '低価格'
END AS price_rank
FROM cars;このSQLでは、priceが4000000でも、最初のprice >= 1500000に当てはまってしまいます。
そのため、高価格ではなく中価格になります。
正しくは、条件の厳しいほうを先に書きます。
SELECT
name,
price,
CASE
WHEN price >= 3000000 THEN '高価格'
WHEN price >= 1500000 THEN '中価格'
ELSE '低価格'
END AS price_rank
FROM cars;Javaのif、else ifでも同じです。
if (price >= 1500000) {
priceRank = "中価格";
} else if (price >= 3000000) {
priceRank = "高価格";
}このJavaコードでも、300万円以上の価格は先に150万円以上の条件に引っかかります。
つまり、高価格判定まで到達しません。
CASE句では、条件の順番が結果を左右します。
範囲が重なる条件を書くときは、必ず上から順に確認してください!
ELSEを書かないとどうなるか
CASE句では、ELSEを省略できます。
ただし、どのWHENにも当てはまらなかった場合はNULLになります。
MySQL公式ドキュメントでも、CASE演算子は条件に一致せずELSEがない場合、NULLを返すと説明されています。
例を見てみましょう。
SELECT
car_id,
name,
status,
CASE status
WHEN 1 THEN '販売中'
WHEN 2 THEN '売約済み'
END AS status_name
FROM cars;このSQLでは、statusが3や9の場合、status_nameはNULLになります。
| status | status_name |
|---|---|
| 1 | 販売中 |
| 2 | 売約済み |
| 3 | NULL |
| 9 | NULL |
NULLになっても問題ない場合は、ELSEなしでも構いません。
しかし、画面表示で使うならELSEを書いたほうが安全です。
CASE status
WHEN 1 THEN '販売中'
WHEN 2 THEN '売約済み'
ELSE '不明'
END AS status_nameJavaのswitch文でも、defaultを書いておくと想定外の値に対応できますよね。
MySQLのCASEでも、ELSEはJavaのdefaultに近い役割です。
CASE句とCASE文の違い
少しややこしいのですが、MySQLにはCASE演算子とCASE文があります。
普段のSELECTでよく使うのは、CASE演算子です。
ストアドプロシージャなどの中で処理分岐に使うものは、CASE文です。
MySQL公式ドキュメントでも、ストアドプログラム用のCASE文はCASE演算子と異なり、ENDではなくEND CASEで終わると説明されています。
| 種類 | 主な使用場所 | 終了の書き方 | 用途 |
|---|---|---|---|
| CASE演算子 | SELECT、ORDER BY、GROUP BYなど | END | 条件に応じて値を返す |
| CASE文 | ストアドプロシージャ、ストアドファンクション | END CASE | 処理の流れを分岐する |
新人エンジニアが最初に覚えるべきなのは、SELECTで使うCASE演算子です。
ストアドプロシージャを使う段階になったら、CASE文も学べばよいです。
Javaのswitch式との比較
最近のJavaでは、switchを式として使う書き方もあります。
switch式は、値を返せます。
String statusName = switch (status) {
case 1 -> "販売中";
case 2 -> "売約済み";
case 3 -> "販売停止";
default -> "不明";
};この書き方は、従来のswitch文よりMySQLのCASE句に近いです。
| 比較 | MySQL CASE | Java switch式 |
|---|---|---|
| 値を返すか | 返す | 返す |
| デフォルト | ELSE | default |
| 使う場所 | SQL | Java |
| 終了 | END | }; |
ただし、実務では「DBで分類すべきか」「Javaで分類すべきか」を考える必要があります。
何でもCASEにする、何でもJavaのswitchにする、どちらも極端です。
CASE句を使うべき場面
CASE句を使うべき場面を整理します。
| 場面 | 理由 | 例 |
|---|---|---|
| 一覧表示用のラベルを作る | DB取得時に表示用の値を作れる | statusを販売中、売約済みに変換 |
| 集計用の分類を作る | 価格帯や年齢層ごとに集計できる | 高価格、中価格、低価格 |
| 並び順を制御する | 単純な昇順・降順ではない順番を作れる | 販売中を先、販売停止を後 |
| NULLや状態値を見やすくする | 画面やレポートでわかりやすい | deleted_atで有効、削除済みを表示 |
| 条件付き集計をする | SUMと組み合わせて件数を数えられる | 価格帯ごとの件数 |
SQLで集計や一覧を作るとき、CASE句は非常に便利です。
特に、管理画面やレポート画面でよく使います。
Javaのswitch文を使うべき場面
一方で、Javaのswitch文を使ったほうがよい場面もあります。
| 場面 | 理由 | 例 |
|---|---|---|
| 業務ロジックを分岐する | DBではなくアプリの処理だから | 支払い方法ごとに処理を変える |
| 複雑な処理を実行する | SQLで書くと読みにくくなる | メール送信、ファイル出力、API呼び出し |
| 状態ごとに別メソッドを呼ぶ | 処理の分岐が主目的だから | 注文状態ごとの処理 |
| 画面側の制御をする | 表示ロジックがアプリ側にあるから | ボタン表示、遷移先変更 |
MySQLのCASE句は、値を作るのが得意です。
Javaのswitch文は、処理を分けるのが得意です。
ここを分けて考えると、設計がきれいになります。
DBでCASEを書くか、Javaでswitchを書くか
実務では、「この分岐はSQLで書くべきか、Javaで書くべきか」で迷うことがあります。
判断の目安を表にします。
| 判断ポイント | SQLのCASE向き | Javaのswitch向き |
|---|---|---|
| 目的 | 取得結果の表示や集計 | 業務処理の分岐 |
| 処理内容 | 値を返すだけ | 複数の処理を実行する |
| 変更頻度 | DB検索条件や帳票寄り | アプリ仕様や画面仕様寄り |
| 読みやすさ | SQL内に書くと自然 | SQLに書くと複雑すぎる |
| 再利用 | 複数画面で同じSQL集計を使う | Java内の複数処理で使う |
たとえば、statusの数値を表示名に変換するだけなら、CASE句でもよいです。
CASE status
WHEN 1 THEN '販売中'
WHEN 2 THEN '売約済み'
ELSE '不明'
END AS status_nameしかし、statusによってメールを送ったり、在庫を更新したり、外部APIを呼んだりするなら、Java側でswitch文を使うべきです。
switch (status) {
case 1:
sendAvailableMail();
break;
case 2:
updateContractInfo();
break;
default:
logUnknownStatus();
break;
}SQLはデータを取り出す場所です。
Javaは業務処理を組み立てる場所です。
役割分担を意識してください。
CASE句でよくあるミス
ミス1:ENDを書き忘れる
CASE句は、必ずENDで閉じます。
悪い例です。
SELECT
name,
CASE
WHEN price >= 3000000 THEN '高価格'
ELSE '通常価格'
FROM cars;ENDがないため、SQLエラーになります。
良い例です。
SELECT
name,
CASE
WHEN price >= 3000000 THEN '高価格'
ELSE '通常価格'
END AS price_rank
FROM cars;ミス2:ELSEを書かずにNULLになる
ELSEを書かないと、どの条件にも当てはまらない場合にNULLになります。
画面表示でNULLが出ると、ユーザーにとってわかりにくい場合があります。
CASE status
WHEN 1 THEN '販売中'
WHEN 2 THEN '売約済み'
END AS status_name
statusが3ならNULLです。不明表示が必要なら、ELSEを書きましょう。
CASE status
WHEN 1 THEN '販売中'
WHEN 2 THEN '売約済み'
ELSE '不明'
END AS status_nameミス3:条件の順番を間違える
範囲条件では、順番がとても重要です。
悪い例です。
CASE
WHEN price >= 1500000 THEN '中価格'
WHEN price >= 3000000 THEN '高価格'
ELSE '低価格'
END良い例です。
CASE
WHEN price >= 3000000 THEN '高価格'
WHEN price >= 1500000 THEN '中価格'
ELSE '低価格'
END条件は上から順番に見られます。
厳しい条件、狭い条件を先に書くのが基本です。
ミス4:複雑な業務ロジックをCASEに詰め込みすぎる
CASE句は便利ですが、何でも詰め込むとSQLが読みにくくなります。
悪い方向に進むと、SELECT文の中に長いCASEが何個も並び、誰も読めないSQLになります。
CASE句は、表示用ラベル、簡単な分類、集計用の条件分岐に使うのが基本です。
複雑な処理はJava側に寄せましょう。
CASE句を使った実務的なSQL例
最後に、carsテーブルを使った実務寄りの例を見てみましょう。
SELECT
car_id,
name,
price,
CASE
WHEN price >= 3000000 THEN '高価格'
WHEN price >= 1500000 THEN '中価格'
ELSE '低価格'
END AS price_rank,
CASE
WHEN deleted_at IS NULL THEN '有効'
ELSE '削除済み'
END AS delete_status
FROM cars
ORDER BY
CASE
WHEN deleted_at IS NULL THEN 1
ELSE 2
END,
price DESC;このSQLでは、次のことをしています。
| 処理 | 内容 |
|---|---|
| price_rank | 価格に応じて高価格、中価格、低価格を表示 |
| delete_status | deleted_atを見て有効、削除済みを表示 |
| ORDER BYのCASE | 有効データを先に、削除済みを後に並べる |
| price DESC | 価格が高い順に並べる |
このように、CASE句は一覧画面や管理画面のSQLでとても役立ちます。
Java側で取得後に加工することもできますが、SQLで自然に書ける表示分類なら、CASE句を使うとシンプルになることがあります。
まとめ
MySQLのCASE句は、SQLの中で条件分岐を行い、条件に応じた値を返すための仕組みです。
Javaのswitch文と似ていますが、目的が違います。
| ポイント | MySQLのCASE句 | Javaのswitch文 |
|---|---|---|
| 主な役割 | 条件に応じて値を返す | 条件に応じて処理を分ける |
| よく使う場所 | SELECT、ORDER BY、GROUP BY、集計 | Javaの業務ロジック |
| デフォルト | ELSE | default |
| 終了 | END | break、return、またはswitch式の終端 |
| 向いていること | 表示用ラベル、分類、条件付き集計 | メール送信、API呼び出し、状態ごとの処理 |
一言でまとめるなら、MySQLのCASE句は「SQLの中で条件に応じた表示値や集計値を作るための分岐」です。
Javaのswitch文は「Javaプログラムの処理そのものを分岐させるための構文」です。
新人エンジニアは、まず次の3つを覚えてください。
| 覚えること | 理由 |
|---|---|
| CASEは値を返す | SELECT結果の1列として使いやすい |
| WHENは上から順番に判定される | 条件の順番を間違えると結果が変わる |
| ELSEを書いたほうが安全 | 想定外の値でNULLになるのを防げる |
今後の学習では、まずSELECT句でCASEを使って表示ラベルを作る練習をしてください。
次にORDER BYで並び順を制御し、最後にSUMやCOUNTと組み合わせた条件付き集計に進むとよいです。
Javaのswitch文と比較しながら、「SQLで値を作るのか」「Javaで処理を分けるのか」を考えられるようになると、DBとアプリの役割分担がかなり理解しやすくなります!
セイ・コンサルティング・グループでは新人エンジニア研修のアシスタント講師を募集しています。
投稿者プロフィール

- 代表取締役
-
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。
学生時代は趣味と実益を兼ねてリゾートバイトにいそしむ。長野県白馬村に始まり、志賀高原でのスキーインストラクター、沖縄石垣島、北海道トマム。高じてオーストラリアのゴールドコーストでツアーガイドなど。現在は野菜作りにはまっている。
最新の投稿
新人エンジニア研修講師2026年6月19日Spring BootでセッションIDがアドレスバーに表示される理由と対策|新人エンジニア向けにJSESSIONIDを解説
新人エンジニア研修講師2026年6月18日JavaのOptionalでnullを安全に扱う方法|NullPointerExceptionを防ぎ、DAOの戻り値をわかりやすくする
新人エンジニア研修講師2026年6月18日ローカルSMTPを使って問い合わせ完了メールを送る方法|新人エンジニア研修向けにSpring BootとJavaMailSenderを解説
新人エンジニア研修講師2026年6月18日DevToolsでHTTP通信・エラー・DOMを確認する方法|新人エンジニア向けにブラウザ開発者ツールを解説
