SQLのCASE WHEN文:条件分岐を使いこなす基本構文
SQLを学習する上で、データに対して条件に応じた処理を行いたい場面は数多くあります。例えば、「特定の条件を満たすデータにフラグを立てたい」「複数の条件に基づいてデータをグループ分けしたい」といったケースです。このような条件分岐を実現するために、SQLにはCASE WHEN文という強力な機能が備わっています。
CASE WHEN文は、プログラミング言語におけるif-then-else文のような役割を果たし、SQLクエリの結果をより柔軟に操作することを可能にします。この構文を理解することで、データ分析の幅が格段に広がるでしょう。
この記事では、SQL初心者の方でも理解できるよう、CASE WHEN文の基本構文から、具体的な利用シーン、そして実践的な例までを分かりやすく解説していきます。
CASE WHEN文の基本構文
CASE WHEN文には、大きく分けて2つの書き方があります。どちらも基本的な考え方は同じですが、記述する際の簡潔さが異なります。
1. シンプルCASE(Simple CASE)
これは、あるカラムの値と、複数の特定の値とを比較する場合に便利です。例えば、statusカラムの値が'pending'なら'処理待ち'、'completed'なら'完了'、それ以外なら'その他'と表示させたい場合などに使用します。
CASE column_name
WHEN value1 THEN result1
WHEN value2 THEN result2
...
ELSE else_result
END
column_name: 条件を判定したいカラム名を指定します。WHEN valueX THEN resultX:column_nameの値がvalueXと一致した場合に、resultXを返します。このWHEN句は複数指定できます。ELSE else_result: どのWHEN句にも一致しなかった場合に返される結果を指定します。ELSE句は省略可能ですが、省略した場合、どの条件にも一致しなければNULLが返されます。END:CASE文の終わりを示します。
2. 検索CASE(Searched CASE)
こちらは、より複雑な条件式を指定したい場合に用います。カラムの値だけでなく、複数のカラムを組み合わせた条件や、比較演算子(>, <, =, <=, >=, !=など)を使った条件を指定できます。
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
ELSE else_result
END
WHEN conditionX THEN resultX:conditionX(条件式)が真(TRUE)である場合に、resultXを返します。このconditionXには、column1 > 100 AND column2 = 'A'のような複雑な論理式を指定できます。ELSE else_result: どのWHEN句の条件式も真(FALSE)でなかった場合に返される結果を指定します。ELSE句は省略可能です。END:CASE文の終わりを示します。
どちらの構文を使うかは、実現したい条件分岐の内容によって選択します。多くの場合、検索CASEの方が汎用性が高く、複雑な条件にも対応できます。
CASE WHEN文の具体的な利用シーンと例
CASE WHEN文は、様々な場面で活用できます。ここでは、いくつか代表的な利用シーンと、具体的なSQLコード例を紹介します。
1. データのカテゴリ分け(グループ化)
数値データや文字列データを、定義した条件に基づいていくつかのカテゴリに分類したい場合に便利です。例えば、年齢層別にユーザーをグループ分けしたり、売上金額に応じて顧客をランク付けしたりする際に使用します。
例:年齢層別のユーザー数集計
usersテーブルにageカラムがあると仮定します。
SELECT
CASE
WHEN age < 20 THEN '10代'
WHEN age >= 20 AND age < 30 THEN '20代'
WHEN age >= 30 AND age < 40 THEN '30代'
WHEN age >= 40 AND age < 50 THEN '40代'
ELSE '50代以上'
END AS age_group,
COUNT(*) AS user_count
FROM
users
GROUP BY
age_group;
このクエリでは、usersテーブルのageカラムの値に基づいて、ユーザーを「10代」「20代」などの年齢グループに分類し、それぞれのグループに属するユーザー数をカウントしています。GROUP BY age_groupで、集計結果を年齢グループごとにまとめています。
2. 条件に基づくフラグ付け・フラグ変更
特定の条件を満たすレコードに、新しいフラグ(印)を付けたり、既存のフラグを変更したりする際に役立ちます。例えば、購入金額が一定額以上の顧客に「優良顧客」というフラグを立てる、といった処理です。
例:購入金額に応じた顧客ランク付け
ordersテーブルにcustomer_idとtotal_amountカラムがあると仮定します。各顧客の総購入金額を計算し、ランクを付けます。
SELECT
customer_id,
SUM(total_amount) AS total_purchase_amount,
CASE
WHEN SUM(total_amount) >= 100000 THEN 'VIP'
WHEN SUM(total_amount) >= 50000 THEN 'Gold'
WHEN SUM(total_amount) >= 10000 THEN 'Silver'
ELSE 'Bronze'
END AS customer_rank
FROM
orders
GROUP BY
customer_id;
この例では、まずSUM(total_amount)で顧客ごとの総購入金額を計算し、その金額に応じてcustomer_rank(顧客ランク)を「VIP」「Gold」「Silver」「Bronze」に分類しています。
3. NULL値の代替値表示
データ分析を行う際、NULL値があると計算ができなかったり、意図しない結果になったりすることがあります。CASE WHEN文を使うことで、NULL値を特定のデフォルト値(例: 0, 'N/A')に置き換えることができます。
例:NULLの割引率を0%で表示
productsテーブルにdiscount_rateカラムがあり、割引がない場合はNULLになっていると仮定します。
SELECT
product_name,
price,
CASE
WHEN discount_rate IS NULL THEN 0
ELSE discount_rate
END AS effective_discount_rate
FROM
products;
このクエリでは、discount_rateがNULLの場合は0を、それ以外の場合は元のdiscount_rateを表示するようにしています。IS NULLという条件式を使っている点に注目してください。
4. 条件による計算結果の切り替え
ある条件によって計算方法を変えたい場合にもCASE WHEN文は有効です。例えば、商品の状態によって割引率を適用したり、適用しなかったりするケースです。
例:在庫状況に応じた価格表示
productsテーブルにprice(通常価格)とstock_quantity(在庫数)カラムがあると仮定します。在庫が少ない(5以下)場合は10%引きで表示します。
SELECT
product_name,
price,
stock_quantity,
CASE
WHEN stock_quantity <= 5 THEN price * 0.9
ELSE price
END AS display_price
FROM
products;
この例では、stock_quantityが5以下の場合はpriceの90%(10%引き)をdisplay_priceとして表示し、それ以外の場合は元のpriceを表示しています。
CASE WHEN文を使う上での注意点
CASE WHEN文は非常に便利ですが、いくつか注意しておきたい点があります。
1. ELSE句の重要性
ELSE句を省略した場合、どのWHEN条件にも一致しないレコードはNULLとして扱われます。意図せずNULL値が発生し、後続の処理に影響を与える可能性があります。特に、集計処理やグループ化を行う前には、ELSE句で全てのケースを網羅できているか確認することが重要です。
2. データ型の一貫性
THEN句やELSE句で返される値は、可能な限り同じデータ型であるべきです。例えば、あるWHEN句で数値を返し、別のWHEN句で文字列を返すと、SQLデータベースによってはエラーになったり、意図しない型変換が行われたりする可能性があります。一般的には、最も汎用性の高いデータ型(例えば、数値と文字列の両方を含む場合は文字列)に自動的に変換されることが多いですが、明確にするためにデータ型を揃えることを推奨します。
3. 処理順序
CASE WHEN文は、WHEN句を上から順に評価し、最初に条件が真(TRUE)になった時点でそのTHEN句の結果を返し、それ以降のWHEN句は評価しません。この性質を利用して、より具体的な条件を先に記述し、一般的な条件を後に記述するといった工夫が可能です。
上記の年齢層の例で言えば、WHEN age < 30を先に書くと、20代のユーザーはすべて「20代」として分類され、その後の「age >= 20 AND age < 30」という条件は評価されなくなってしまいます。そのため、より詳細な条件を先に記述することが重要です。
4. パフォーマンスへの影響
CASE WHEN文は強力な機能ですが、非常に複雑な条件を多数記述したり、巨大なテーブルに対して適用したりすると、クエリの実行速度に影響を与える可能性があります。パフォーマンスが問題になる場合は、インデックスの活用や、クエリの見直しを検討しましょう。しかし、多くの場合、CASE WHEN文による可読性や柔軟性の向上は、パフォーマンスへのわずかな影響を上回るメリットがあります。
まとめ
CASE WHEN文は、SQLで条件分岐を実現するための非常に強力で柔軟な構文です。データのカテゴリ分け、フラグ付け、NULL値の代替、計算結果の切り替えなど、様々なシーンで活用できます。
基本構文を理解し、ELSE句の重要性やデータ型の一貫性に注意することで、CASE WHEN文を効果的に使いこなし、より高度なデータ分析やレポート作成が可能になります。
ぜひ、今回の解説を参考に、実際のデータでCASE WHEN文を使ってみてください。きっと、SQLによるデータ操作の可能性が広がるはずです。