Oracle SQL 関数 : SIGN : 符号チェック

 numberRet := SIGN( numberSrc );

 SIGNは数値データnumberSrcが0(ゼロ)より小さい場合は-1を返し、numberSrcが0(ゼロ)の
  場合は0(ゼロ)を返し、numberSrcが0(ゼロ)より大きい場合は1を返します。
  numberSrcは数値を返す式を指定できます。
SQL> SELECT SIGN(-12),SIGN(0),SIGN(10) FROM DUAL;

 SIGN(-12)    SIGN(0)   SIGN(10)
---------- ---------- ----------
        -1          0          1

このSIGN関数と前述のDECODE関数を組み合わせることで、割と複雑なことが可能になります。
以下に簡単な例を示します。

SQL> SELECT EMPNO,SAL,DECODE(SIGN(SAL - 1500),-1,'1500未満',0,'1500同じ',1,'1500より大きい') FROM EMP;

     EMPNO        SAL DECODE(SIGN(SA
---------- ---------- --------------
      7369        800 1500未満
      7499       1600 1500より大きい
      7521       1250 1500未満
      7566       2975 1500より大きい
      7654       1250 1500未満
      7698       2850 1500より大きい
      7782       2450 1500より大きい
      7788       3000 1500より大きい
      7839       5000 1500より大きい
      7844       1500 1500同じ
      7876       1100 1500未満

     EMPNO        SAL DECODE(SIGN(SA
---------- ---------- --------------
      7900        950 1500未満
      7902       3000 1500より大きい
      7934       1300 1500未満

14行が選択されました。


さらに SIGN 関数と前述の DECODE 関数を組み合わせる例を示します。
「TM_担当者」の部門コードでコードの値が「1」の担当者のみを「1」として返し、 その他を「0」として返します。

SQL> SELECT DECODE(SIGN(部門コード - 1), 0, 1, 0) FROM TM_担当者;

DECODE(SIGN(部門コード-1),0,1,0)
--------------------------------
                               1
                               1
                               1
                               1
                               0
                               0
                               0
                               0
                               0

9行が選択されました。

そこで部門コードが「2」の担当者のみを「1」その他を「0」とする DECODE 関数処理と、 部門コードが「3」の担当者のみを「1」その他を「0」とする DECODE 関数処理を追加します。
そうすると、以下の様に部門コード毎に対応するレコードが抽出できます。

SQL> SELECT
  2   DECODE(SIGN(部門コード - 1), 0, 1, 0) AS 部門1
  3  ,DECODE(SIGN(部門コード - 2), 0, 1, 0) AS 部門2
  4  ,DECODE(SIGN(部門コード - 3), 0, 1, 0) AS 部門3
  5  FROM TM_担当者;

     部門1      部門2      部門3
---------- ---------- ----------
         1          0          0
         1          0          0
         1          0          0
         1          0          0
         0          1          0
         0          1          0
         0          0          1
         0          0          1
         0          0          1

9行が選択されました。

上の例の「部門1」「部門2」「部門3」のところで SUM 関数をとってやれば、 一括で部門毎の件数が取得できます。

SQL> SELECT
 2   SUM(DECODE(SIGN(部門コード - 1), 0, 1, 0)) AS 部門1
 3  ,SUM(DECODE(SIGN(部門コード - 2), 0, 1, 0)) AS 部門2
 4  ,SUM(DECODE(SIGN(部門コード - 3), 0, 1, 0)) AS 部門3
 5  FROM TM_担当者;

    部門1      部門2      部門3
--------- ---------- ----------
        4          2          3