1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【ORACLE】NULL大全集

Last updated at Posted at 2025-02-01

【背景】

オラクルマスターSilver SQLを受験してやっぱりNULLの扱いって微妙だなーって思ったのでそんなに物量ありませんが、まとめました!
ORACLEの現場にいる方だったら割とピンとくる気がしますがNULLの扱いが面倒ですよね、、(別にオラクルじゃなくてもそうか、、)
後から見て振り返りやすい様にまとめたので良かったらチラ見程度で参考にしていってください。


目次

1.NULLとは
2.NULLの判定・扱い
3.NULLを考慮する・しない処理(関数)
4.実際の開発現場でのNULL事象
5.体験記


1.NULLとは

======================

『NULLは空文字の扱い』

======================

NULLは通常のデータと違い違った扱いをする為、開発案件や見積り調査等で
NULLを扱う際は十分な注意が必要になります。


2.NULLの判定・扱い

そのテーブルのその項目がNULLであるかどうかを判定する際は以下のように判定します。

NULL関連ファンクション例 NVL
--テーブル:test
name       nenrei
---------- -------- 
test1       61
test2       24
test3       

--testテーブルの「nenrei」カラムがNULLのレコードを取得する
SELECT name, nenrei FROM test where nenrei IS NULL;
--結果: 
name       nenrei
---------- -------- 
test3       

--testテーブルの「nenrei」カラムがNULLではないレコードを取得する
SELECT name, nenrei FROM test where nenrei IS NOT NULL;
--結果: 
name       nenrei
---------- -------- 
test1       61
test2       24

下記の様には判定できません。

× 『= NULL』
× 『= ''』

NULL関連ファンクション例 NVL
--テーブル:test
name       nenrei
---------- -------- 
test1       61
test2       24
test3       

--testテーブルの「nenrei」カラムがNULLのレコードを「= NULL」判定で取得する
SELECT name, nenrei FROM test where nenrei = NULL;
--結果: レコードが選択されませんでした。

--testテーブルの「nenrei」カラムがNULLのレコードを「= ''」判定で取得する
SELECT name, nenrei FROM test where nenrei = '';
--結果: レコードが選択されませんでした。

・NULLの算術式や文字列の連結

NULLを計算や文字列の結合に使用する際は以下のような動作をします。
計算処理での出力結果が空文字(NULL)になってしまったりと注意が必要になります。
⇨NULLを考慮した処理を実装する必要があることもある

NULL関連ファンクション例 NVL

--NULLと数値を計算する
SELECT NULL + 10 FROM dual;
--結果:     ※空文字(NULL)

--NULLとNULLを文字列結合する
SELECT NULL || NULL FROM dual;
--結果:     ※空文字(NULL)

--NULLと文字列を文字列結合する
SELECT NULL || 'test' FROM dual;
--結果:test

・ORDER BY句でのNULLの動作

【注意点】NULLは一番大きい値として扱われる

NULL関連ファンクション例 NVL
--テーブル:test
name       nenrei
---------- -------- 
test1       61
test2       24
test3       

--testテーブルの「nenrei」カラムにて昇順でレコードを取得する
SELECT name, nenrei FROM test ORDER BY nenrei ASC;
--並べ換え結果:
name       nenrei
---------- -------- 
test2       24
test1       61
test3       

--testテーブルの「nenrei」カラムにて降順でレコードを取得する
SELECT name, nenrei FROM test ORDER BY nenrei DESC;
--並べ換え結果:
name       nenrei
---------- -------- 
test3       
test1       61
test2       24

備考:
DESC(降順)にてNULLデータを最後に持ってきたい場合は「NULLS LAST」を使用する様にしましょう。
※「NULLS FIRST」もあります。「NULLS FIRST」「NULLS LAST」についての説明は割愛いたします。


3.NULLを考慮する・しない処理(関数)

--カウントする処理や集計する処理は注意が必要

関数 処理内容
COUNT(*) NULLも含めた件数を取得する
DITINCT(列名) NULLを排除した上で重複業を排除した結果を出力

・集計ファンクション

下記、集計ファンクションにて〇〇(列名)とするとNULLを排除した動作になる。
例:SUM(列名), AVG(列名), MAX(列名), MIN(列名), COUNT(列名)

ファンクション 説明
SUM 合計を求める
AVG 平均値を求める
MAX 最大値を求める
MIN 最小値を求める
COUNT 行数をカウントする
NULLを考慮する・しない処理(関数)
--テーブル:test
name       nenrei
---------- -------- 
test1       61
test2       24
test3       
test4       30
test5       30

--testテーブルの「nenrei」カラムを「*」でレコードを取得する
SELECT COUNT(*) FROM test;
--結果:5

--testテーブルの「nenrei」カラムをCOUNTでレコードを取得する
SELECT COUNT(nenrei) FROM test;
--結果:4

--testテーブルの「nenrei」カラムをDISTINCTにてレコードを取得する
SELECT DISTINCT(nenrei) FROM test;
--結果:
nenrei
-------- 
61
24
30
--※NULLを排除した動作

--testテーブルの「nenrei」カラムにて昇順でレコードを取得する
SELECT COUNT(DISTINCT(nenrei)) FROM test;
--結果:3 ※一つ上の結果をカウントした結果

--testテーブルの「nenrei」カラムを集計ファンクション「AVG」でレコードを取得する
SELECT AVG(nenrei) FROM test;
--結果:36.25 ※(61+24+30+30)/4

--testテーブルの「nenrei」カラムを集計ファンクション「AVG」でレコードを取得する
--NULLを考慮した処理を実施
SELECT AVG(NVL(nenrei,0)) FROM test;
--結果:29 ※(61+24+0+30+30)/5

・NULL関連ファンクション

テーブルの制約にて NOT NULL制約を用いていないカラムについてなど
上記でも解説した通り集計する際などにNULLデータがカウント(件数取得)されていない為、正しく集計されない場合があります。
PL/SQLの現場などにいらした方ならピンとくると思いますがNVLやNVL2で変換している処理がたくさんあるかと思います。

ファンクション 説明
NVL NULLを指定した値に置き換える
NVL2 NULLかどうかに応じて異なる値を戻す
NULLIF 値が等しい場合にNULLを戻す
COALESCE 複数の値のうち、最初に見つかった非NULL値を戻す
NULL関連ファンクション例 NVL
--test3の「nenrei」カラムがNULL
SELECT name, nenrei FROM test;

name       nenrei
---------- -------- 
test1       61
test2       24
test3       

----------------------------------------------------------------------
--NVLを使用した場合
SELECT name, NVL(nenrei,0) FROM test;

name       nenrei
---------- -------- 
test1       61
test2       24
test3       0
NULL関連ファンクション例 NVL2
--NVL2:第1引数がNULLではない場合は、第2引数を取得。
--     第1引数がNULLの場合は、第3引数を取得
--test3の「nenrei」カラムがNULL
SELECT name, nenrei FROM test;

name       nenrei
---------- -------- 
test1       61
test2       24
test3       

----------------------------------------------------------------------
--NVL2を使用した場合
SELECT name, NVL2(nenrei, nenrei, XX) FROM test;

name       nenrei
---------- -------- 
test1       61
test2       24
test3       XX -- ⇨test3に元々「44」と入っている場合は「44」と出力される。

5.体験記

実際の開発案件での体験

実際の開発案件にてテーブルのカラム追加を行なった際に仕様からNULLに対して許容するか否かをお客様へ確認を行った経験がありました。
カラム追加をしたテーブル関してはフロントのオンライン画面でも見えるところだった為、もしNULLが流れてきた場合はオンライン画面上どう見せたいか、また、NULLがデータとして流れてくることによってシステムエラー等で落ちないかどうかを考慮したりデグレード試験をどの程度実施する必要があるかなどを考える必要が出てきていました。

NULLをテーブルレベルから許容するか否かを設計フェーズより前にて判断するのは当時の私にとってはかなり大変な思考でしたが今回のようなこうした知識があればもう少し判断に余裕を持たせられたのかなって思っています!

【前提】
カラム追加するテーブルにはNOT NULL制約は付けておらず、また、デフォルトの設定もしていなかった為、NULLのデータが流れてくる仕様


一読頂いてありがとうございます❗️❗️

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?