( New ) 新連載スタート!2人の会話形式でPythonを学ぶ「週末Pythonゆる講座」はこちら ▶▶

【SQL】CASE|条件によってデータを分類する

CASEとは?

CASE(ケース)

(ある特定の)場合、(個々の具体的な)事例、(警察などの介入・調査を要する)事件、事実、真相、実情、(人の)状態、立場、境遇

Weblio英和辞書

CASE」とは「ある特定の場合…」という英語の意味があります

SQLでも同様に「〇〇の場合は●●」という使い方をします

しかし、CASE文はSQL学習者にとって難関の一つです…

しっかりと利用イメージを頭に浮かべて、利用してみてください

CASEの利用イメージ

CASE文のイメージは条件による「分類」です

データを振り分けることができます

プログラミング用語(と若者言葉)で「フラグを立てる」とも言いますね

Flagイメージ

そして「分類」したものを「新たな列(カラム)」として扱うことができます

つまりCASE文のイメージは…

「条件による分類を行い、新しい列(カラム)を作る」

なぜデータを分類するのか?

ずばり、「集計を簡単にするため」です

テストの点数データを考えてみましょう

データを取得・蓄積するときは最も細かい単位で貯めるため

「0点、1点、2点、3点…98点、99点、100点」

すると、このようなデータになります

テストの点数(詳細)

情報が細かすぎて分析に向きません

そこで点数に応じて「優秀」「普通」「落第」と3段階で分類してみましょう

  • 80点以上なら「優秀
  • 50点以上で80点未満なら「普通
  • 50点未満なら「落第
テストの点数(まとめ)

3つに分類することで、データを塊として扱うことができるため

データが処理しやすく」なりました

CASE文の使い方

CASE文は「SELECT句」でのみ利用が可能です

CASE文の中に「WHEN」「THEN」「ELSE」「END」を組み合わせます

SELECT

CASE

WHEN 条件式① THEN 【分類名①】

WHEN 条件式② THEN 【分類名②】

WHEN 条件式③ THEN 【分類名③】

ELSE 【分類名(その他)】

END

FROM ***

「CASE文」はSQLの中でも最も長い構文の一つです

しっかりとイメージができるよう、ステップごとにご説明していきます

使うデータは「テストの点数」で、そこに「評価」を3段階で付けていきます

CASE文イメージ
CASE:始まりの合図

SELECT

CASE ←始まりの合図を出す

WHEN:条件を記載する

SELECT

CASE

WHEN 点数 >= 80 ←1つ目の条件式(80点以上)を記入

THEN:条件に当てはまった場合の「分類名」を記入

SELECT

CASE

WHEN 点数 >= 80 THEN ‘優秀’ ←条件式に当てはまるときの分類名(優秀)を記入

必要な分だけ条件式の組み合わせ(WHEN+THEN)を記入

SELECT

CASE

WHEN 点数 >= 80 THEN ‘優秀’

WHEN 点数 < 80 and 点数 >= 50 THEN ‘普通’ ←2つ目の条件式と分類名

WHEN 点数 < 50 THEN ‘落第’ ←3つ目の条件式と分類名

ELSE:条件式に当てはまらないときの分類名を記入

SELECT

CASE

WHEN 点数 >= 80 THEN ‘優秀’

WHEN 点数 < 80 and 点数 >= 50 THEN ‘普通’

WHEN 点数 < 50 THEN ‘落第’

ELSE ‘その他’ ←条件式に当てはまらない場合の分類名(その他)を記入

END:CASE文の終わりを明示する

SELECT

CASE

WHEN 点数 >= 80 THEN ‘優秀’

WHEN 点数 < 80 and 点数 >= 50 THEN ‘普通’

WHEN 点数 < 50 THEN ‘落第’

ELSE ‘その他’

END ←CASE文がここで終わることを記入する

CASE文自体に名前を付ける

SELECT

CASE

WHEN 点数 >= 80 THEN ‘優秀’

WHEN 点数 < 80 and 点数 >= 50 THEN ‘普通’

WHEN 点数 < 50 THEN ‘落第’

ELSE ‘その他’

END AS ‘評価’ ←CASE文(分類)自体に「評価」という名前を付ける

改めてお題を元にSQLを抽出してみます!

お題

「テスト点数テーブルから名前と点数を抽出する。その際、80点以上なら「優秀」、50点以上なら「普通」、それ未満なら「落第」とする評価を付ける」

SELECT
    名前, 点数,
    CASE
        WHEN 点数 >= 80 THEN '優秀'
        WHEN 点数 < 80 and 点数 >= 50 THEN '普通'
        WHEN 点数 < 50 THEN '落第'
        ELSE 'その他'
    END AS '評価'
FROM
    テスト点数テーブル
CASE文イメージ

点数」に応じて「評価」を付けることができました

CASEの注意点

① 新たなカラムを作るイメージを持つ

CASE文は非常に複雑なため、条件式で頭がいっぱいになってしまいます

一番肝心な「条件による分類を行い、新しい列(カラム)を作る」を忘れてしまうことがあります

CASE文で「分類カラム」を作ることをしっかりイメージしましょう

CASE文イメージ

② カンマを打つ場所

SELECT句で(,)カンマを打つのはどこでしょうか?

複数列(カラム)がある場合には「列名」と「列名」の間にカンマを打ちます

SELECT
    名前, クラス, 性別, 部活, 点数

「CASE文は新しい列」ですので、同じ定義に当てはまります

つまり他の「列名」と「CASE文」の間にカンマを打ちます

(CASE文の中にカンマは入りません!)

SELECT
    名前, クラス, 性別, 部活, 点数, 
    CASE
        WHEN 点数 >= 80 THEN '優秀'
        WHEN 点数 < 80 and 点数 >= 50 THEN '普通'
        WHEN 点数 < 50 THEN '落第'
    ELSE 'その他'
    END AS '評価'
注意

CASE文は「CASE」から始まり「END」で終わりますが

その間に(,)カンマを打ってしまうエラーがとても多いので注意しましょう

SELECT

CASE

WHEN 点数 >= 80 THEN ‘優秀’, ←カンマ不要

WHEN 点数 < 80 and 点数 >= 50 THEN ‘普通’, ←カンマ不要

WHEN 点数 < 50 THEN ‘落第’, ←カンマ不要

ELSE ‘その他’

END AS ‘評価’,  ←カンマ必要

名前, クラス, 性別

FROM ***

③ 「ELSE」は書いておく

CASE文では条件の最後に「ELSE」と書くことで

WHENに当てはまらない場合」の分類名を明示することができます

基本的には「WHEN」内に全てのデータを網羅できるようにします

しかし思った条件に当てはまらない場合やデータが「NULL」だった時に備えて

「ELSE ‘その他’」のように記載しておきましょう

④ 条件が重複した場合の処理

CASE文のWHEN内の条件が重複した場合は、

先に書いたWHEN条件が優先」されます

それでは、「条件が重複」とはどういう状況でしょうか?

テスト点数で「100点」だった生徒には「満点」とするCASE文を書いてみます

CASE

WHEN 点数 >= 80 THEN ‘優秀’ ←この条件にも100点が当てはまる

WHEN 点数 < 80 and 点数 >= 50 THEN ‘普通’

WHEN 点数 < 50 THEN ‘落第’

WHEN 点数 = 100 THEN ‘満点’ ←最後にも100点の条件を設定する

ELSE ‘その他’

END

CASE文イメージ

結果を見ると「100点」を取った人が「満点」ではなく「優秀」になっています

理由は先のWHEN条件である「80点以上」に「100点」が含まれるためです

つまり、CASE文のWHEN条件は

  1. 漏れ/かぶりが無いようにする
  2. 優先したい条件は先に書く

この2つを意識しましょう

ルールを逆手に取る!?

テスト点数の事例で「普通」の条件として、「80点未満」と「50点以上」の複数条件を記載していますが…

WHEN 点数 < 80 and 点数 >= 50 THEN ‘普通’

実は優先したい条件を先に書くことで、1つの条件だけで十分になります

WHEN 点数 >= 100 THEN ‘満点’

WHEN 点数 >= 80 THEN ‘優秀’

WHEN 点数 >= 50 THEN ‘普通’

ELSE ‘落第’

まとめ

CASE文は【JOIN】【サブクエリ】に並ぶ、難関ポイントです

しっかりと利用イメージを頭に入れてましょう

「条件による分類を行い、新しい列(カラム)を作る」

コメントを残す

メールアドレスが公開されることはありません。