Oracleで条件をわけるには通常WHERE句を使用しますが、SELECT句で「CASE」を使って条件をわけることもできます。
SQLの中でも「CASE」は非常に使い勝手のいいSQLです。「CASE」の使い方をぜひマスターしたいところです!
2種類のCASE
CASEでは「値で判定するCASE」と「式で判定するCASE」の2種類あります。
1. CASE(値で分岐)
--CASEで条件をわけてSELECTする SELECT CASE 列名 WHEN 値1 THEN 結果1 WHEN 値2 THEN 結果2 ELSE 結果3 END FROM table1;
これは「CASE」を使う一番シンプルなパターンです。「値」で分岐した結果を返します。あまり使用しないかもしれません。
2. CASE(式で分岐)
--CASEで条件をわけてSELECTする SELECT CASE WHEN 条件1 THEN 条件1の結果 WHEN 条件2 THEN 条件2の結果 ELSE 条件1,2以外の結果 END FROM table1;
こちらが最もよく使用する「CASE」の分岐です。「条件式」を使う事ができるため幅が広がります。
WHENで条件式を記述し、SELECTしたい結果をTHENのあとに記述します。「CASE」の最後は「END」でしめくくります。
それでは、「CASE」の使い方のいくつかのパターンを紹介します。
サンプルデータ
s_no | s_name | reader_f | gender |
A001 | 佐藤花子 | 1 | 女 |
A002 | 田中太郎 | 2 | 男 |
A003 | 加藤一 | 0 | 男 |
A004 | 青木花 | 0 | 女 |
A005 | 藤田学 | 1 | 男 |
例1. CASEで条件分岐するパターン
--CASEで学級委員・書記だけマークする SELECT s_no, CASE reader_f WHEN 1 THEN s_name || '/学級委員' WHEN 2 THEN s_name || '/書記' ELSE s_name END s_name, reader_f FROM student;
s_no | s_name | reader_f |
A001 | 佐藤花子/学級委員 | 1 |
A002 | 田中太郎/書記 | 2 |
A003 | 加藤一 | 0 |
A004 | 青木花 | 0 |
A005 | 藤田学/学級委員 | 1 |
この例の「CASE」では、学級委員の名前に「/学級委員」をつけ、書記の名前に「/書記」をつけてSELECTしています。
これを「CASE」を使わずにWHERE句で条件分けしたとしたら結構面倒ですね。
例2. CASEで条件分岐をするパターン(式あり)
--CASEで学級委員・書記だけマークする SELECT s_no, CASE WHEN reader_f = 1 AND gender = '男' THEN s_name || '/学級委員(男子)' WHEN reader_f = 1 AND gender = '女' THEN s_name || '/学級委員(女子)' ELSE s_name END s_name, reader_f FROM student;
s_no | s_name | reader_f |
A001 | 佐藤花子/学級委員(女子) | 1 |
A002 | 田中太郎 | 2 |
A003 | 加藤一 | 0 |
A004 | 青木花 | 0 |
A005 | 藤田学/学級委員(男子) | 1 |
ここでは「CASE式」で条件分岐しています。
「式」が使えるので複雑な分岐に対応できます。ここでは2つの条件に合致したレコードにコメントをつけました。
男子の学級委員、女子の学級委員にコメントをつけてSELECTしました。
例3. CASEで大小比較するパターン
--CASEで90点以上→A,70点以上→B,以外→CをSELECT SELECT s_no, s_name, CASE WHEN score >= 90 THEN 'A' WHEN score < 90 AND score >= 70 THEN 'B' ELSE 'C' END FROM student;
「CASE」では大小比較もできます。
テストの点数が90点以上、70点以上、70点未満の3種類を「CASE」で振り分け、それぞれSELECTする記号をわけています。
例4. CASEでワイルドカードを使用するパターン
--CASEで佐藤さんは○、加藤さんは□をSELECT SELECT s_no, s_name, CASE WHEN s_name like '佐藤%' THEN '○' WHEN s_name like '加藤%' THEN '□' ELSE null END name_f FROM student;
s_no | s_name | name_f |
A001 | 佐藤花子 | 〇 |
A002 | 田中太郎 | |
A003 | 加藤一 | □ |
A004 | 青木花 | |
A005 | 藤田学 |
「CASE」ではワイルドカードを使用してあいまい条件も指定できます。ここでは苗字が佐藤、加藤の人だけ〇、□をつけてSELECTしました。
例5. CASEで集計するパターン
--CASEで男女の数をSELECT SELECT SUM(CASE WHEN gender = '男' THEN 1 ELSE 0 END) m_cnt, SUM(CASE WHEN gender = '女' THEN 1 ELSE 0 END) f_cnt FROM student;
m_cnt | f_cnt |
3 | 2 |
こちらは「CASE」で条件分岐して集計するパターンです。
男子・女子の人数をそれぞれ一度に集計しています。男なら1、女なら1を返し、1をSUMして集計しています。COUNTのような数を集計しています。このようにすると条件に合致した件数を求めることができます。
where句でわけると複数のSQLに分かれて煩雑ですが、CASEなら一発です。
CASEのまとめ
「CASE」の使い方をいくつかのパターンで紹介しました。
「CASE」はSQLの中でも「使えるテクニック」なのでおススメです。「CASE」を使いこなすことができれば、脱初心者といってよいですね。
「CASE」が使えるとSQLのコード量が大幅に省略できて楽になるメリットもあります。
参照:問合せにおけるCASE式の使用 – Oracle Database 2日で開発者ガイド
以上、OracleのCASEの使い方とパターンでした。
コメント