L
o
a
d
i
n
g
.
.
.

ホーム

お知らせ

製品・ソリューション

サービス

導入事例・パートナー

EXEM Academy・ブログ

会社情報

採用情報

2022.02.16

SQLチューニング(第24回)「DECODE & CASE WHENの理解および条件ステートメントの処理」(2/2)

 今回は、「DECODE & CASE WHENの理解および条件ステートメントの処理」の2回目「CASE」についてのお話です。それでは、早速はじめましょう。


7.2 CASE

 CASEはOracleにおいてDECODEと同じようにIF – THEN – ELSEを表現できる構文で、特定条件に合うデータを抽出したり条件どうし比較処理してデータを抽出したい場合に手軽に使うことができます。

7.2.1 構文

CASE  [ expression ]
  WHEN condition_1 THEN result_1
  WHEN condition_2 THEN result_2
  ...
  WHEN condition_n THEN result_n
  ELSE result
END

7.2.2 構文に対する詳細説明

(1)CASE

 SQLでCASE構文を始める時に使用します(宣言)。

(2)WHEN

 比較条件を記述する部分で、条件(CONDITION_1)がTRUEならTHEN節の値をリターンします(RESULT_1)。FALSEならば以後のWHEN節の条件(CONDITION_2~N)に対してTRUEなのかFALSEなのか比較しながら対応する値を抽出します

(3)ELSE

 WHEN節の比較が全部FALSEである場合ELSE節の値をリターンします。 もし、ELSE節がないならばNULLをリターンすします。 ELSE節はIF文のELSEのような役割を実行します。

7.2.3 単純CASEと探索CASE使用法

7.2.3.1 単純CASE式

 値を比較する方式がDECODEを使った構文とほとんど似ていて、表現式および比較カラムはCASE後すぐに羅列します。

例)SELECT EMPNO,ENAME,
               CASE DEPTNO WHEN 10 THEN '会計'
                           WHEN 20 THEN '研究'
                           WHEN 30 THEN '営業'
                           WHEN 40 THEN '運営'
               END "部署名"
      FROM EMP

7.2.3.2 条件検索CASE使用法

 最も大きい長所だと見ることができます。 CASEはWHEN節すぐ後に表現式または、比較カラムが書かれて、より精巧な条件式を簡単に作成することができます。

SELECT EMPNO,
       ENAME,
       CASE WHEN SAL < 1800 THEN 'F等級'
             WHEN SAL >= 1800 AND SAL < 3000 THEN 'E等級'
             WHEN SAL >= 3000 AND SAL < 4500 THEN 'D等級'
             WHEN SAL >= 4500 AND SAL < 6000 THEN 'C等級'
             WHEN SAL >= 6000 AND SAL < 8000 THEN 'B等級'
             WHEN SAL >= 8000 THEN 'A等級'
       END
FROM EMP

7.2.4 例を用いたCASEの使用法

7.2.4.1 CASEに対する詳細説明とDECODEの表現方法

 CASEの詳細説明を行うとともに、DECODEに変換しながら、その使用法を調べてみましょう。 可読性と便宜のためにSQLは省略して核心の部分だけ表記するようにします。

(例題1)CASE 9+1 WHEN 10 THEN ‘正解’ END

説明:9+1が10なのか比較後TRUEですので’正解’をリターンします。
もし、FALSEならNULLをリターンします。

ロジック:IF 9+1 = 10 THEN
           RETURE '正解';
        END IF
変換:DECODE(9+1,10,'正解')

(例題2)ASE 9+1 WHEN 9 THEN ‘正解1’ WHEN 10 THEN ‘正解2’ END

説明:9+1が9と同じなのか比較して結果はFALSEですので、二番目WHEN節に移動して10と同じなのか比較します。 10に対しては条件式がTRUEですので、’正解2’をリターンします。 もし、二つともFALSEだった場合にはNULLをリターンします。

ロジック:IF 9+1 = 9 THEN
           RETURN ‘正解1’
        ELSIF 9+1= 10 THEN
           RETURN ‘正解2’
        END IF;
変換:DECDOE (9+1,9,‘正解1’、10,‘正解2’)

(例題3)CASE 9+1 WHEN 9 THEN ‘正解1’ WHEN 10 THEN ‘正解2’ ELSE ‘正解3’ END

説明:9+1と9を比較すると結果はFALSEです。 したがって二番目WHEN節比較をします。 9+1と10を比較するとTRUEなので‘正解2’をリターンします。 もし、9+1でなく9+2ならばELSE節の‘正解3’をリターンします。

ロジック:IF 9+1 = 9 THEN
           RETURN ‘正解1’
        ELSE IF 9+1= 10 THEN
           RETURN ‘正解2’
        ELSE
           RETURN ‘正解3’
        END IF;
変換:DECODE (9+1,9,'正解1',10,'正解2','正解3')

実戦例題(重複CASE)

 スキー用品店A社の2011年12月の日付別販売目標量にともなう販売実績達成度合いに対するSQLを作成してみみましょう。 ただし、決定された販売目標量は全部同一であり詳しい条件は下記のとおりとします。

 2011/12/07は実績を計算しない日です。 2011/12/07を除く日付のうち、販売目標より販売量が低い場合、備考欄に「未達成」のフレーズとともに目標量と比較して不足した数値を示し、販売量が目標量より高い場合は「達成」というフレーズを抽出します。 また、2011/12/07の場合、備考欄に「未実績対象」と表記することとする。理解を助けるためにこれらの条件の簡単なフローチャートを描くことと以下の通りとなります。

 前で説明した部分をCASE構文でSQLを作成すれば次のとおりとなります。

SELECT sale_dt ,
       SUM( target ) ,
       SUM( salecnt ) ,
       CASE
          WHEN sale_dt <> '20111207' AND  SUM( target ) > SUM( salecnt )
          THEN '未達性:' ||( SUM( target ) - SUM( salecnt ) )
       ELSE
          CASE sale_dt
             WHEN '20111207'
             THEN '米実績対象'
          ELSE '達成'
          END
       END
  FROM decode_t1
GROUP  BY sale_dt

 これまで、SQLでプログラムのIF文のように条件文として機能するDECODEとCASEに対する使用方法とパフォーマンスの問題について調べてみました(第23回・第24回)。 プログラムの助けを借りずにSQLでデータを比較し、分岐して処理できるという点は非常に大きな利点と考えられます。 しかし、SQLに初めて触れる読者は、DECODEとCASEを習得するのに苦労します。 したがって、私はフローチャートとPL / SQLのIFステートメントを使用してできるだけ簡単に理解できるように努力しました。 ここではDECODEとCASEがもたらす利点を積極的に活用し、欠点はよく克服して効率的に使用するのに役立つことを願っています。


 いかがでしたでしょうか?2回に渡りお届けいたしました「DECODE & CASE WHENの理解および条件ステートメントの処理」を終了します。次回以降は、「NULL処理構文の理解と効率的なSQLの作成」と題しまして、7回シリーズでお送りする予定です。ご期待くだだい。では See you ^^


PHP Code Snippets Powered By : XYZScripts.com