SQL入門CASE式は「変身ベルト」だ!SELECTの中で条件分岐する魔法の構文

変換後 データベース

データベースから取り出したデータに応じた場合分け

データベースからデータを取り出すとき、そのままの姿では使いにくいことがあります。

「性別が『1』って何だよ。男って書けよ」
「点数が『85』じゃなくて、合格か不合格かだけ教えてくれ」

データを取ってきてから、ExcelやPHPで加工していませんか。
それは二度手間になってしまいます。

SQLには、データを取得する瞬間に中身を別の値に書き換える魔法があります。
それが「CASE(ケース)」式です。

これは、SQLの中に埋め込める「if文(条件分岐)」です。
今日は、無機質なデータを人間に分かりやすい言葉に変身させる、この便利な構文を解説します。


基本構文:WHENとTHENのリズム

CASE式の書き方は独特ですが、リズムさえ覚えれば簡単です。

  • CASE (これから場合分けするぞ)
  • WHEN 条件 THEN 結果 (もしこうなら、こう変身しろ)
  • ELSE 結果 (それ以外なら、これになれ)
  • END (変身完了)
SELECT 名前,
  CASE
    WHEN 条件A THEN '条件AにあてはまったのでAだよ'
    WHEN 条件B THEN '条件BにあてはまったのでBだよ'
    ELSE 'その他'
  END
FROM テーブル名;Code language: PHP (php)

SELECTの列を指定する場所に、この長い呪文をねじ込みます。
すると、条件に合った値に書き換わって出力されます。

これで「名前」は、以下の3つのどれに該当したかによって姿を変えます。

  • 条件Aに該当したのか?
  • 条件Bに該当したのか?
  • 条件Aにも条件Bにも該当しなかったのか?

このブログでたびたび解説しているPHPで書くと、以下のようなイメージです。

// もしPHPで書くなら...
if (条件A) {
    $name = '条件AにあてはまったのでAだよ';
} elseif (条件B) {
    $name = '条件BにあてはまったのでBだよ';
} else {
    $name = 'その他';
}Code language: PHP (php)

PHPのif文の分岐では{で開始して}で終了するのが通常ですが、SQLではCASEで初めてENDで終了するのです。

PHPのif文と同様で、上の条件にあてはまったらそこで終了となり、下のWHENは実行されないので注意です。

これは、ifにあてはまったらその直後のelseifが実行されないのと同じです。

前述の通り、if文とCASE式は似ているので、対応イメージを以下の表に示します。

PHPのif文SQLのCASE式
if (条件A) {CASE WHEN 条件A
$res = ‘Aだよ’; THEN ‘Aだよ’
} elseif (条件B) {WHEN 条件B
$res = ‘Bだよ’; THEN ‘Bだよ’
} else {ELSE
$res = ‘その他’; ‘その他’
}END

具体例:男と女を人間に戻す

よくあるデータベース設計では、性別を数字で管理しています。
1が男性、2が女性、といった具合です。

これをそのまま画面に出すと、ユーザーは混乱します。

どんな設計かにもよりますが、CASE式を使って、取得時に日本語に変換する方が便利なこともあります。やってみましょう。

SELECT name,
  CASE
    WHEN gender = 1 THEN '男性'
    WHEN gender = 2 THEN '女性'
    ELSE '不明'
  END AS gender_text
FROM users;Code language: PHP (php)

これで、結果は「1」ではなく「男性」と表示されます。

AS gender_text と書くことで、この新しい列に名前をつけています。

この名前をつけてわかりやすくする構文のことを、「別名」とか、「エイリアス」と言います。

PHPで例えると、$arr[‘gender_text’]のように、連想配列のキーを決めているようなイメージです。

上記のようにCASE式で「男性」や「女性」のように翻訳済の文言をセットした場合、プログラム側でif (gender == 1)…と書く必要はありません。

SQLが気を利かせて、最初から翻訳済みのデータを渡してくれるのです。

1や2といった値に対応する文言はPHPなどのサーバサイド言語側で決めたい!という場合はSQLでCASE式で翻訳することなく、そのままPHP側に1や2といった値を渡すと良いでしょう。


応用:点数でランク付けする

数字の範囲で条件分岐することも可能です。

テストの点数(score)に応じて、通知表のようなランクをつけてみましょう。

SELECT name, score,
  CASE
    WHEN score >= 90 THEN 'Sランク'
    WHEN score >= 80 THEN 'Aランク'
    WHEN score >= 60 THEN 'Bランク'
    ELSE '追試確定'
  END AS rank
FROM tests;Code language: PHP (php)

上から順番に判定されます。
95点の人は、最初の score >= 90 に引っかかるので「Sランク」になります。

50点の人は、どれにも引っかからないので ELSE の「追試確定」になります。

これで、冷酷な数字の羅列が、意味のある評価リストに早変わりします。


注意点:ENDを忘れると・・・!?

CASE式を書くとき、初心者が一人残らず必ずやるミスがあります。
最後のENDの書き忘れです。

-- エラーになる例
  CASE
    WHEN score >= 60 THEN '合格'
  ELSE '不合格'
-- ここにENDがない!Code language: PHP (php)

END がないと、データベースはどこまでが条件分岐なのか分かりません。

「まだ続くのか? まだ条件があるのか?」と待ち続け、最終的に構文エラーを吐いて倒れます。

「SQLではCASEで初めてENDで終了」と前述しましたが、「CASEで始めたらENDで締める」。
これはセットです。

お箸は2本で1膳。CASEはENDとセットで1人前です。


まとめ:SQLでできることはSQLでやろう

  • CASE WHEN THEN:条件に合わせて値を変身させる。
  • ELSE:どれにも当てはまらない場合の受け皿。
  • END:終わりの合図。忘れずに!

データを取得した後、PHPやExcelなどでチマチマ加工するのは、スーパーで買った魚を自宅で捌くようなものです。

場合によってそれが手段として適切か否か、見極めていきましょう。

CASE式を使えば、スーパー(データベース)の時点で「三枚おろし」にして渡してくれます。

料理(アプリ開発)の手間を減らすために、下処理はSQLに任せちゃいましょう。

コメント

タイトルとURLをコピーしました