OracleでNULLを置き換える(NVL・COALESCE・CASE式)

OracleでNULLを置き換える(NVL・COALESCE・CASE式)

記事の文字数:3284

OracleでNULLを扱う方法を徹底解説します。NVL・COALESCE・CASE式の使い分けからUPDATEによる置き換え、テーブル定義例によるSQLから空文字との違いまで詳しく説明します。

OracleデータベースでNULLをどう扱うかは、業務アプリの正確性・可読性・パフォーマンスに直結します。本記事では「oracle null 置き換え」をテーマに、NVL/COALESCEを用いた表示上の置き換え、UPDATEでの永続的な置き換え、さらには実務での注意点を網羅します。

記事のポイント

  • OracleのNULLは「不明値」。空文字もNULL扱い。
  • 表示置き換えはNVL/COALESCE/CASEを使う。
  • UPDATEでの更新は WHERE col IS NULL を指定。
  • 空文字=NULLの仕様を理解することが重要。

oracleのnull置き換え

NULLはデータベースにおいて「不明/未定義」を意味する特別な値です。数値型・日付型・文字列型すべてで発生し得ます。

  • Oracleでは空文字(”)もNULLとみなされる点に注意。PostgreSQLやMySQLでは空文字とNULLは区別されるため、移植性を考えると挙動を正確に理解することが重要です。
  • 比較演算(=, <>)ではNULLを判定できないため、必ず IS NULL / IS NOT NULL を使います。

NULLを画面やレポートに出すと「空欄」になり、ユーザーに誤解を与えることがあります。そのため、表示上の置き換えが必須です。

実際のテーブル定義例

事前登録データ(DDL)
-- employeesテーブル(人事情報)
-- DROP TABLE employees PURGE;
CREATE TABLE employees (
emp_id NUMBER(6) PRIMARY KEY,
first_name VARCHAR2(50),
last_name VARCHAR2(50),
phone VARCHAR2(20),
salary NUMBER(10,2),
hire_date DATE
);
INSERT INTO employees (emp_id, first_name, last_name, phone, salary, hire_date) VALUES
(1001, 'Taro', 'Yamada', NULL, 300000, DATE '2020-04-01');
INSERT INTO employees (emp_id, first_name, last_name, phone, salary, hire_date) VALUES
(1002, 'Hanako', 'Suzuki', '09012345678', NULL, DATE '2021-01-15');
INSERT INTO employees (emp_id, first_name, last_name, phone, salary, hire_date) VALUES
(1003, 'Ken', 'Tanaka', '', 500000, NULL);
INSERT INTO employees (emp_id, first_name, last_name, phone, salary, hire_date) VALUES
(1004, 'Taro', NULL, '08000000000', 400000, DATE '2022-03-01');
COMMIT;
-- contactsテーブル(連絡先情報)
-- DROP TABLE contacts PURGE;
CREATE TABLE contacts (
contact_id NUMBER(6) PRIMARY KEY,
name VARCHAR2(100),
email VARCHAR2(100),
phone VARCHAR2(20)
);
INSERT INTO contacts (contact_id, name, email, phone) VALUES
(2001, 'Sato Ichiro', NULL, '08099998888');
INSERT INTO contacts (contact_id, name, email, phone) VALUES
(2002, 'Miyamoto Kana', 'kana@example.com', NULL);
INSERT INTO contacts (contact_id, name, email, phone) VALUES
(2003, 'Kobayashi Jun', NULL, NULL);
COMMIT;
-- ordersテーブル(注文情報)
-- DROP TABLE orders PURGE;
CREATE TABLE orders (
order_id NUMBER(6) PRIMARY KEY,
customer VARCHAR2(100),
discount NUMBER(5,2)
);
INSERT INTO orders (order_id, customer, discount) VALUES
(3001, 'Client A', NULL);
INSERT INTO orders (order_id, customer, discount) VALUES
(3002, 'Client B', 10);
INSERT INTO orders (order_id, customer, discount) VALUES
(3003, 'Client C', NULL);
COMMIT;
事前登録データ(テーブル)

employeesテーブル

EMP_IDFIRST_NAMELAST_NAMEPHONESALARYHIRE_DATE
1001TaroYamada未登録300000.002020/04/01 0:00:00
1002HanakoSuzuki09012345678NULL2021/01/15 0:00:00
1003KenTanaka未登録500000.00NULL
1004TaroNULL08000000000400000.002022/03/01 0:00:00

contactsテーブル

CONTACT_IDNAMEEMAILPHONE
2001Sato IchiroNULL08099998888
2002Miyamoto Kanakana@example.comNULL
2003Kobayashi JunNULLNULL

ordersテーブル

ORDER_IDCUSTOMERDISCOUNT
3001Client ANULL
3002Client B10.00
3003Client CNULL

このような典型的な人事テーブルで、電話番号などがNULLの場合に既定値を設定するケースを想定します。

NVLによるnullの置き換え

構文
NVL(expr1, expr2)
-- expr1 : 評価対象の式(NULL かもしれない値)
-- expr2 : expr1 が NULL のときに返す値
SELECT NVL(phone, '未登録') AS phone
FROM employees;

実行結果

PHONE
未登録
09012345678
未登録
08000000000

NULLなら第2引数の値を返します。Oracle固有関数で、簡潔に書けますが型変換に注意が必要です。

NVL2によるnullの置き換え

構文
NVL2(expr, value_if_not_null, value_if_null)
-- expr : 評価対象の式
-- value_if_not_null : expr が NULLでない場合に返す値
-- value_if_null : expr が NULLの場合に返す値

NVL が「NULLなら置き換え」だけなのに対して、NVL2 は「NULLと非NULLの両方に対応できる」のが特徴です。

SELECT NVL2(last_name, first_name, '(空)')
FROM employees;

実行結果

NVL2(LAST_NAME,FIRST_NAME,‘(空)‘)
Taro
Hanako
Ken
(空)

非NULLなら第2引数を、NULLなら第3引数を返します。条件分岐が明示できるため便利です。

COALESCEによるnullの置き換え

構文
COALESCE(expr1, expr2, expr3, ... , exprN)
-- 左から順番に評価され、最初に見つかったNULLでない値を返します。
-- すべてがNULLなら NULLを返す。
SELECT COALESCE(email, phone, '不明')
FROM contacts;

実行結果

COALESCE(EMAIL,PHONE,‘不明’)
08099998888
kana@example.com
不明

複数の候補から最初に見つかった非NULL値を返します。ANSI標準で移植性が高いのが特徴です。

CASE式によるnullの置き換え

SELECT CASE WHEN discount IS NULL THEN 0 ELSE discount END
FROM orders;

実行結果

CASEWHENDISCOUNTISNULLTHEN0ELSEDISCOUNTEND
0
10
0

discountがNULLの場合は0を返却します。 条件分岐を自由に書けるため、複雑な業務ルールや型が混在する場面で役立ちます。

実データを更新してNULLを置き換える

UPDATEの基本形

UPDATE employees
SET phone = '未登録'
WHERE phone IS NULL;

更新前(SELECT * FROM employees;

EMP_IDFIRST_NAMELAST_NAMEPHONESALARYHIRE_DATE
1001TaroYamadaNULL300000.002020/04/01 0:00:00
1002HanakoSuzuki09012345678NULL2021/01/15 0:00:00
1003KenTanakaNULL500000.00NULL
1004TaroNULL08000000000400000.002022/03/01 0:00:00

更新後(SELECT * FROM employees;

EMP_IDFIRST_NAMELAST_NAMEPHONESALARYHIRE_DATE
1001TaroYamada未登録300000.002020/04/01 0:00:00
1002HanakoSuzuki09012345678NULL2021/01/15 0:00:00
1003KenTanaka未登録500000.00NULL
1004TaroNULL08000000000400000.002022/03/01 0:00:00

これでphone列がNULLの行に「未登録」を設定します。WHEREを必ず付与して不要な更新を避けましょう。

oracle null 置き換え — データ型別の活用例

-- 数値型: NULLを0に置き換えて集計
SELECT SUM(NVL(salary,0)) FROM employees;
-- 日付型: NULLを特定日付に置き換える
SELECT NVL(hire_date, DATE '2000-01-01') FROM employees;
-- 文字列結合: NULLを空文字に置き換え
SELECT NVL(first_name,'') || ' ' || NVL(last_name,'') AS full_name
FROM employees;

空文字とNULLの違い

  • Oracleでは空文字 = NULL。INSERTで”を入れてもNULLとして格納されます。
  • ユニーク制約ではNULLは「異なる値」と見なされるため、複数行にNULLを入れても違反しません。
  • しかしアプリが空文字とNULLを区別していると、整合性問題を引き起こします。

oracle null 置き換え — よくあるFAQ

Q. NVLとCOALESCEの違いは?

項目NVLCOALESCE
引数の数2つのみ2つ以上(可変長)
処理内容expr1がNULLならexpr2を返す最初にNULLでない値を返す
  • NVLを使う場合

    • 単純に「NULLをデフォルト値に置き換えたい」とき
    • 例:給与、手数料、在庫数のNULLを0にする
  • COALESCEを使う場合

    • 複数の候補カラムからNULLでない値を優先的に取得したいとき
    • 例:電話番号(携帯 → 自宅 → 会社)、住所(現住所 → 本籍 → 登録住所)

Q. 実データのNULLを埋めるべき? → UI表示だけなら関数利用で十分。マスタデータや参照整合性が必要な場合はUPDATEを推奨。

Q. 空文字を残したい場合は? → Oracleでは不可能。代替として特殊文字(例:’ ‘や’-‘)を利用する設計が必要。

OracleにおけるNULL置き換えのまとめ

  1. 表示置き換えは NVL / COALESCE を使う。
  2. 永続化するなら UPDATE ... WHERE col IS NULL をバッチ処理で。
  3. 空文字とNULLの違いを理解して設計する。
  4. 「NULL」「0」「未登録」を混同しないよう要件を整理する。

以上で本記事の解説を終わります。
よいITライフを!
Scroll to Top