汎用関数の問題
変換関数という言い方はしないけれど、「値がNULL
だったら、指定した値に変えて出力する」という関数NVL
があります。Oracleにのみ、古いバージョンから提供されていて、Oracleの開発者の間では有名な関数の1つです。一方、Oracleユーザーになじみが薄い(?)と思われるNULLIF
やCOALESCE
という関数がありますが、これらはANSI/規格の関数です。使いこなせるのはNVL
だけでは困ります。
問2
次を確認してください。
SQL> SELECT empno,comm,sal FROM emp; EMPNO COMM SAL ---------- ---------- ---------- 7369 800 7499 300 1600 7521 500 1250 7566 2975 7654 1400 1250 7698 2850 7782 2450 7839 5000 7844 0 1500 7900 950 7902 3000 7934 1300
COMM列の値がNULL
であれば、SAL列の10%を返すSQLをすべて選びなさい。
- a. SELECT empno,NVL(comm,sal*0.1) AS comm FROM emp;
- b. SELECT empno,NVL2(comm,comm,sal*0.1) AS comm FROM emp;
- c. SELECT empno,NVL2(NULLIF(sal,NVL(comm,sal)),comm,sal*0.1) AS comm FROM emp;
正解は、選択肢a、b、cです(全選択肢が正解という設問は、実際の試験にはありません)。
設問の関数は次のとおりです。
関数 | 説明 |
---|---|
NVL(列値) | 列値がNULLならば値を返す |
NVL2(列値, 値1, 値2) | 列値がNULLならば値2を返し、NULL以外であれば値1を返す |
NULLIF(列1, 列2) | 列1と列2が等価ならばNULLを返し、非等価ならば列1の値を返す |
実行結果は次のとおりです。
SQL> --選択肢a SQL> SELECT empno,NVL(comm,sal*0.1) AS comm FROM emp; EMPNO COMM ---------- ---------- 7369 80 7499 300 7521 500 7566 297.5 7654 1400 7698 285 7782 245 7839 500 7844 0 7900 95 7902 300 7934 130 SQL> --選択肢b SQL> SELECT empno,NVL2(comm,comm,sal*0.1) AS comm FROM emp; EMPNO COMM ---------- ---------- 7369 80 7499 300 7521 500 7566 297.5 7654 1400 7698 285 7782 245 7839 500 7844 0 7900 95 7902 300 7934 130 SQL> --選択肢c SQL> SELECT empno,NVL2(NULLIF(sal,NVL(comm,sal)),comm,sal*0.1) AS comm FROM emp; EMPNO COMM ---------- ---------- 7369 80 7499 300 7521 500 7566 297.5 7654 1400 7698 285 7782 245 7839 500 7844 0 7900 95 7902 300 7934 130
選択肢cは、頭の中で関数の実行結果をトレース(処理の過程を頭の中で追いかけていくこと)できないと、正解か否か判断できません。
「そんな無理やり使わなくても」と思ったでしょうが、試験では、入れ子になった関数がいろんなところ(結合や副問合せDMLなど)で登場します。結合について理解できていても、入れ子になった関数の結果を追い間違えて(トレースできなくて)正解の選択肢を見つけられなかったということがあり得ます。入れ子になった関数は面倒くさがらず落ち着いてトレースしてください。
試験会場では、ペンとメモ用紙みたいなものを渡してくれるので、入れ子の内側の結果から順に、メモしていけば良いでしょう。