OracleのSQLのNVL関数についてまとめています。
SQLのNVLの構文
NVLはOracle独自の関数で、NULLを文字列に置換して問い合わせ結果に含めることが可能です。第一引数がNULLの場合、第2引数を戻します。NULLでない場合は、第一引数を戻します。
SELECT last_name, NVL(TO_CHAR(commission_pct), 'Not Applicable') commission FROM employees WHERE last_name LIKE 'B%' ORDER BY last_name; LAST_NAME COMMISSION ------------------------- ---------------------------------------- Baer Not Applicable Baida Not Applicable Banda .1 Bates .15 Bell Not Applicable Bernstein .25 Bissot Not Applicable Bloom .2 Bull Not Applicable
【関連記事】
▶【ハンズオン】SQLのNVL関数とは?概要や使い方を丁寧に説明! | 「ポテパンスタイル」
値の比較をする場合、対象がNULLだと様々な例外処理が必要になってくるため、NVLで空文字(からもじ)などに変換したほうが、処理をシンプルにできるんですね。
ただし、NVLは主要DBMSの中ではOracleでしか利用できないため、他のDBMSにSQLを流用等する場合は、coalsceやIFNULL(MySQL)、case式等で置き換える必要があります。
OracleのNVLのリファレンスマニュアル
Oracleのnvlの引数は、任意のデータ型を使用できますが、データ型が異なる場合は暗黙的にデータ型変換されます。
- 第一引数が文字データの場合、Oracle Databaseは2つの引数を比較する前に第2引数を第一引数のデータ型に変換し、第一引数のキャラクタ・セットでVARCHAR2を戻します。
- 第一引数が数値である場合、Oracle Databaseは数値の優先順位が最も高い引数を判断し、その引数のデータ型に他方の引数を暗黙的に変換して、そのデータ型を戻します。
なお、nvlはCOALESCEやCASE式での代替が可能です。
Oracleにnvlが用意されているのは、引数2つでシンプルにNULL代替を記述できるという点だと思います。スッキリ記述して、SQLコードの可読性をあげることができるんですね。
代替のCOALESCEは単語自体が長く直感的にコードの意味がわかりにくいです。CASE式は都度記述しているとコードが冗長になってしまいます。
NVLは、Null Value Logicの略で、単語も短く、パッと見てわかりやすいのがメリットです。
NVLをcoalesceで代替する例
coalesceでNVLを書き換えてみましょう。
select nvl(VAL_1,'') from table1;
以下のようになります。単にnvlをcoalsceに書き換えるだけで、引数の数も順序も同じです。
select coalsce(VAL_1,'') from table1;
ただし、coalsceは複数の引数を指定することができ、引数を最初からNULL判定して、NULLでないものを返り値として返すんですね。
以下のケースでは、list_price(定価)の0.9倍、min_price(最低価格)ともにNULLだった場合には5を返り値として返します。
SELECT product_id, list_price, min_price, COALESCE(0.9*list_price, min_price, 5) "Sale" FROM product_information WHERE supplier_id = 102050 ORDER BY product_id; PRODUCT_ID LIST_PRICE MIN_PRICE Sale ---------- ---------- ---------- ---------- 1769 48 43.2 1770 73 73 2378 305 247 274.5 2382 850 731 765 3355 5
【関連記事】
▶SQL coalesce 値がNULLの場合の代替値を返す 簡易版のNVLやNULLIFが使えるDBもあり
第一引数がNULLなら第二引数、第二引数がNULLなら第三引数…と複数の値を指定する場合にはNVLでは対応できませんし、case式だと長くなりすぎます。
上記のような場合のNULL代替処理は、coalesceが最適と言えるでしょう。
NVLをcase式で代替する例
NVLをcase式で書き換えてみましょう。以下のSQLは、table1のカラムVAL_1を抽出する例です。VAL_1がNULLの場合は空文字として抽出します。
select nvl(VAL_1,'') from table1;
CASE式で書き換えるとこうなります。
select CASE WHEN VAL_1 IS NULL THEN '' WHEN VAL_1 IS NOT NULL THEN VAL_1 END from table1;
関連)SQLのCASE式サンプル集 order byやgroup byとの組み合わせもバッチリ
単にNULL代替させるだけならcase式だとコードが冗長になってしまします。
しかし、case式だとNULL判定以外にも複雑な条件を組み込めるんですね。プログラム的なロジックを組み込むように、複数の値の判定や別の値の参照が可能です。複雑な処理を組み込みたい場合は、NVLよりもcase式が適していると言えるでしょう。
NVLとNVL2の違い
Oracleには、NVL2という関数が用意されています。NVLとの違いは、指定した値がNULL以外のときに、別の値を返すことができる点です。
select nvl2(VAL_1,1,'') from table1;
上記のように記述すると、こうなります。
- VAL_1がNULLの場合は空文字を返します。
- VAL_1がNULLの場合は1を返します。
まとめ
- NVLは、NULLの代替値を返すOracle独自の関数
- Oracle以外では、coalsceやcase式で置き換えることが可能
- NVL2は、指定した値がNULL以外のとき、別の値を返すことができる