【SQL】CASE式の書き方:サンプル多数あり


ここではORACLEデータベースのSQLで、CASE式の基本的な書き方や使い方について紹介します。

CASE式を使うことで、条件分岐させて値を変換することが出来ます。

CASE式以外にもSELECT文のサンプルは↓で紹介していますので参考にしてください。
>>【SQL】SELECT文の書き方:サンプル多数あり

CASE式の基本構文

CASE式は、式や列の値によって条件分岐させて値を変換することが出来ます。

CASE式は、SELECT文だけでなく、UPDATE文やDELETE文でも使うことが出来ます。

CASE式の基本文法は次の通りです。
条件に一致するときに返す値や条件に一致しないときに返す値を記述します。

CASE WHEN 条件式 THEN 条件に一致する時に返す値
     [ELSE 条件に一致しなかった時に返す値]
END

CASE式を使ったSQLサンプル

ここからは実際にCASE式を使ったSQLのサンプルを紹介します。

CASE式をSELECT句で使う方法

SELECT文のSELECT句でCASE式を使う方法を紹介します。

次のSQLでは、TAB1テーブルのSCORE列の値が80以上の場合、’合格’という文字列を返します。80に満たない場合は’不合格’と返します。

SELECT
    name
    ,CASE WHEN score >= 80 THEN '合格'
          ELSE '不合格'
    END
FROM
    tab1
;

CASE式をWHERE句で使う方法

CASE式はWHERE句でも使うことが出来ます。

次のSQLでは、CASE式を使って、COL1列の値が80以上ならAという文字列を返し、Aという文字列と一致するレコードだけを抽出しています。

SELECT
    *
FROM
    tab1
WHERE
    (CASE WHEN col1 >= 80 THEN 'A' END) = 'A'
;

CASE式で条件式を省略する方法

CASE式では、条件式を省略することもできます。

次のSQLでは、SCORE列の値が100のとき、’満点’という文字列を返し、100以外のとき、’満点ではありません’という文字列を返します。

SELECT
    name
    ,CASE score WHEN 100 THEN '満点'
                ELSE '満点ではありません'
    END
FROM
    tab1
;

CASE式で複数条件を指定する方法

CASE式では、複数の条件式を指定することが出来ます。

複数条件を指定するときは、WHEN~を追加していきます。

次のSQLでは、SCORE列の値に応じたランクを返しています。SCORE列の値が80以上であればAという文字列、60以上であればB、40以上であればC、40未満はDとなります。

SELECT
    name
    ,CASE WHEN score >= 80 THEN 'A'
          WHEN score >= 60 THEN 'B'
          WHEN score >= 40 THEN 'C'
          ELSE 'D'
    END
FROM
    tab1
;

上記の使い方に加え、複数条件を一度に指定することもできます。

次のSQLでは、「score1 >= 80 AND score2 >= 80」として2つの条件をANDで並べて使っています。演算子を組み合わせることで複数の条件を指定することが出来ます。

SELECT
    name
    ,CASE WHEN score1 >= 80 AND score2 >= 80 THEN 'A'
          WHEN score1 >= 80 OR score2 >= 80 THEN 'B'
          ELSE 'C'
    END
FROM
    tab1
;

CASE式でNULL値の判定や置換する方法

CASE式で、列の値がNULL値の場合に他の値や文字列に置き換えることが出来ます。

NULL値の判定を行うときは、条件式に「列名 IS NULL」や「列名 IS NOT NULL」と記述します。

次のSQLでは、SCORE列がNULLの場合は0を返して置換しています。NULL出ない場合は、そのままSCORE列の値を返しています。

SELECT
    name
    ,CASE WHEN score IS NULL THEN 0
          ELSE score
    END
FROM
    tab1
;

次のSQLでは、SCORE列の値がNULL値のとき、’受験済み’という文字列を返し、NULLのときは’未受験’という文字列を返しています。

SELECT
    name
    ,CASE WHEN score IS NOT NULL THEN '受験済み'
          ELSE '未受験'
    END
FROM
    tab1
;

NULL値レコードの扱いや置換方法については別ページにも記載しています。
詳しくは「【SQL】列の値やNULL値を置き換える方法」で紹介していますのでぜひ参考にしてください・

CASE式を入れ子する方法

CASE式は入れ子にして使うこともできます。

次のSQLでは、AGE列が20以上の場合に、SCORE列の値によってランクを返しています。AGE列が20未満の場合は、’対象外’という文字列を返します。

SELECT
    name
    ,CASE WHEN age >= 20 THEN
            CASE WHEN score >= 80 THEN 'A'
                 WHEN score >= 60 THEN 'B'
                 WHEN score >= 40 THEN 'C'
                 ELSE 'D'
            END
          ELSE '対象外'
     END
FROM
    tab1
;

CASE式をEXISTSで使う方法

CASE式はEXISTSでも使うことが出来ます。

次のSQLでは、TAB1テーブルのCOL1列の値をCASE式で変換して、EXISTSの条件として指定しています。

SELECT
    a.*
FROM
    tab1 a
WHERE
    EXISTS (SELECT
                'x'
            FROM
                tab2 b
            WHERE
                b.col2 = (CASE WHEN a.col1 = 'A01001' THEN '001'
                               WHEN a.col1 = 'B01001' THEN '002'
                          END)
            )

CASE式でLIKEを使う方法

CASE式では、LIKE演算子を使って、条件式を記述することもできます。

次のSQLでは、JOB_ID列の値を前方一致検索し、該当するグループをA,B,Cと振り分けています。

SELECT
    name
    ,CASE WHEN job_id LIKE 'A001%' THEN 'A'
          WHEN job_id LIKE 'B001%' THEN 'B'
          WHEN job_id LIKE 'B002%' THEN 'C'
          ELSE 'D'
    END
FROM
    tab1
;

この他にもLIKE演算子を組み合わせ、曖昧検索など様々な使い方があります。
詳しくは「【SQL】LIKE条件の書き方:サンプル多数あり」で紹介していますのでぜひ参考にしてください。

CASE式をUPDATE文で使う方法

CASE式をUPDATE文で使うことで、条件分岐させて列の値を更新することが出来ます。

次のSQLでは、SCORE列の値に応じて、SCORE_RANK列を更新しています。

UPDATE
    tab1
SET
    score_rank = CASE WHEN score >= 80 THEN 'A'
                      WHEN score >= 60 THEN 'B'
                      WHEN score >= 40 THEN 'C'
                      ELSE 'D'
                 END
;

CASE式をDELETE文で使う方法

CASE式をDELETE文で使うことで、条件分岐させて列の値を更新することが出来ます。

次のSQLでは、TAB1テーブルの列の値を’001’や’002’に変換し、変換した値を元にしてTAB2テーブルの該当レコードを削除しています。

DELETE FROM
    tab2 b
WHERE
    b.col2 IN (SELECT
                  CASE WHEN a.col1 = 'A01001' THEN '001'
                       WHEN a.col1 = 'B01001' THEN '002'
                  END
               FROM
                  tab1 a
               )
;

CASE式とDECODE関数の違い

DECODE関数とCASE式の大きな違いは、条件に比較演算子や式を使うことが出来ないことです。

例えば、DECODE関数の検索値に「 >= 100」と比較演算子を使うことは出来ません。かといって「COL1 >= 100」として式を検索値に指定することもできません。

比較演算子や式を使った条件分岐にはCASE式を使います。
DECODE関数については↓で解説していますので参考にしてください。
>>【ORACLE】DECODE関数の書き方:サンプル多数あり

その他

CASE式でELSEを省略する

CASE式では、ELSEを省略することが出来ます。

次のSQLではELSEを書いていません。SCORE列の値が80以上の場合は’合格’という文字列を返します。80未満の場合はNULLを返します。

SELECT
    name
    ,CASE WHEN score >= 80 THEN '合格'
    END
FROM
    tab1
;

CASE式で条件に一致しないとき何もしない

CASE式で条件に一致しないとき、列の値をそのまま取得することもできます。

次のSQLでは、SCORE列の値がNULL値のとき、’未受験’という文字列を返します。
NULLでないときは、SCORE列の値をそのまま何もしないで返します。

SELECT
    name
    ,CASE WHEN score IS NULL THEN '未受験'
          ELSE score
    END
FROM
    tab1
;

まとめ

CASE式は式や列の値を条件分岐させて値を変換することが出来ます。

SELECT文だけでなく、UPDATE文やDELETE文でも使うことが出来るので覚えておくと便利です。

この他にも、SELECT文には様々な機能や使い方があります。
詳しくは「【SQL】SELECT文の書き方:サンプル多数あり」で解説していますのでぜひ参考にしてください。