CASE式の魅力を学ぼう!

この記事を書いた人
仲宗根 武
CASE式とは
・SQLで条件分岐の記述が可能になります。
・SELECTやUPDATEで使用可能なため汎用性があります。
CASE式のメリット
・主要なRDBMSでは問題なく利用可能なため汎用性が高い。(Oracleであれば「DECODE関数」というものがありますが、Oracleでしか使用できないため汎用性が低いです。)
・SQLの可読性もパフォーマンスも向上することが可能。
CASE式の種類
・単純CASE式
CASE 列
WHEN 条件1 THEN 結果1
WHEN 条件2 THEN 結果2
ELSE デフォルト値
END
・検索CASE式
CASE
WHEN 列 = 条件1 THEN 結果1
WHEN 列 = 条件2 THEN 結果2
ELSE デフォルト値
END
単純CASE式で記述可能な条件は、検索CASE式でも記述することが可能です。
CASE式の注意点
・ELSE部分は省略可能だが、エラーの原因になるため設定しておきましょう。
・各分岐での返すデータ型を統一する。
・ENDの記述漏れは、構文エラーになります。
内容
1.異なる条件の集計を1つのSQLで行うことが可能!
部署ごとで男性/女性の人数の集計を考えた場合、通常であればWHERE句でそれぞれ異なる条件を記述して2回SQLを発行します。
2回SQLを発行する場合、単純計算コストが倍かかってしまいます。
他にも、手法はありますが複雑になったり可読性が下がったりしてしまいます。
そこでCASE式を使えば、1つのSQLで実現可能になります。
#部署表
| department_name(部署) | sex(性別) | number_of_people(人数) |
|---|---|---|
| 営業部 | 1 | 15 |
| 営業部 | 2 | 11 |
| 開発部 | 1 | 16 |
| 開発部 | 2 | 17 |
| 経理部 | 1 | 14 |
| 経理部 | 2 | 11 |
| 事業部 | 1 | 8 |
| 事業部 | 2 | 19 |
| 人事部 | 1 | 20 |
| 人事部 | 2 | 20 |
| 製造部 | 1 | 18 |
| 製造部 | 2 | 17 |
| 総務部 | 1 | 2 |
| 総務部 | 2 | 11 |
#集計結果
| 部署 | 男性 | 女性 |
|---|---|---|
| 営業部 | 15 | 11 |
| 開発部 | 16 | 17 |
| 経理部 | 14 | 11 |
| 事業部 | 8 | 19 |
| 人事部 | 20 | 20 |
| 製造部 | 18 | 17 |
| 総務部 | 2 | 11 |
#WHERE句で条件を用いたSQL
SELECT
department_name
, number_of_people
FROM
TmpTbl WHERE sex = '1';
SELECT
department_name
, number_of_people
FROM
TmpTbl WHERE sex = '2';
#CASE式を用いたSQL
SELECT
department_name
, SUM(CASE WHEN sex = '1' THEN number_of_people ELSE 0 END) AS cnt_man
, SUM(CASE WHEN sex = '2' THEN number_of_people ELSE 0 END) AS cnt_woman
FROM
TmpTbl
GROUP BY
department_name;
#集計結果
| department_name | cnt_man | cnt_woman |
|---|---|---|
| 営業部 | 15 | 11 |
| 開発部 | 16 | 17 |
| 経理部 | 14 | 11 |
| 事業部 | 8 | 19 |
| 人事部 | 20 | 20 |
| 製造部 | 18 | 17 |
| 総務部 | 2 | 11 |
同じ結果が取得できました。
2.UPDATEでも使用可能!
製品種類ごとで価格の更新を行いたい場合、1つずつUPDATEを行えば変更可能ですがCASE式を用いることにより1回のUPDATEで更新が可能になります。
#更新条件
・調味料の価格(price)を1割引き
・乳製品の価格(price)を4割増し
・青果の価格(price)は変更なし
#製品表
| product_type | product_name | price |
|---|---|---|
| 調味料 | ごま油 | 200 |
| 青果 | サクランボ | 300 |
| 乳製品 | チーズ | 250 |
| 青果 | スイカ | 560 |
| 調味料 | 砂糖 | 230 |
| 乳製品 | 牛乳 | 123 |
| 乳製品 | ヨーグルト | 59 |
| 調味料 | 味噌 | 394 |
| 青果 | ざくろ | 545 |
| 調味料 | 醤油 | 234 |
| 調味料 | 酢 | 435 |
| 青果 | すだち | 434 |
#1件ずつの場合
UPDATE TmpTbl2
SET price = price * 0.9
WHERE product_type = '調味料'
UPDATE TmpTbl2
SET price = price * 1.4
WHERE product_type = '乳製品'
#CASE式を用いた場合
UPDATE TmpTbl2
SET price = CASE WHEN product_type = '調味料' THEN price * 0.9
WHEN product_type = '乳製品' THEN price * 1.4
ELSE price
END
#実行結果
| product_type | product_name | price |
|---|---|---|
| 調味料 | ごま油 | 180 |
| 青果 | サクランボ | 300 |
| 乳製品 | チーズ | 350 |
| 青果 | スイカ | 560 |
| 調味料 | 砂糖 | 207 |
| 乳製品 | 牛乳 | 172 |
| 乳製品 | ヨーグルト | 82 |
| 調味料 | 味噌 | 354 |
| 青果 | ざくろ | 545 |
| 調味料 | 醤油 | 210 |
| 調味料 | 酢 | 391 |
| 青果 | すだち | 434 |
条件通りの結果となりました。
まとめ
今回は、「CASE式」の魅力について取り上げました。
しかし、今回取り上げた内容はほんの一部でしかありません。
これ以外にも色々なメリットがありますので是非他の使い方もマスターしていきましょう。
M&TTでは、「わくわく」を実現する仲間を募集しています!
皆様のご応募お待ちしております!
