この記事について
第2章の後編では、試験で頻繁に問われる「NULL」と「DISTINCT」の挙動を整理します。NULLは「値がない」という特殊な状態で、算術・比較・連結など、あらゆる操作に影響します。動作を正確に理解しておくと、試験の引っかけ問題に対処しやすくなります。
NULLの扱い
NULLとは
NULLとは「値が存在しない・不明である」状態を表します。ゼロ(0)や空白文字とは異なります。
NULLが格納される場面
以下の操作をすると、列にNULLが設定されます。
| 場面 | 例 |
|---|---|
INSERT時に列値に NULL を明示する |
INSERT INTO employees (id, name) VALUES (1, NULL); |
| INSERT時に列および列値を省略する |
INSERT INTO employees (id) VALUES (1);(name列がNOT NULL制約なければNULLになる) |
UPDATEで列値に NULL を指定する |
UPDATE employees SET name = NULL WHERE id = 1; |
空文字 '' を格納する |
INSERT INTO employees (id, name) VALUES (1, '');(⚠後述) |
🔑 Oracle特有の重要注意点:空文字はNULLとして扱われる
Oracleでは、空文字
''(長さ0の文字列)はNULLとして格納されます。これはMySQL・SQL Serverなど他のDBとは異なる挙動で、試験でも問われます。-- Oracle では空文字を入れるとNULLになる INSERT INTO test (name) VALUES (''); -- nameはNULLとして格納される
算術式でのNULLの挙動
NULLを含む算術式は、必ず結果がNULLになります。
SELECT NULL + 10 FROM DUAL; -- 結果:NULL
SELECT NULL * 100 FROM DUAL; -- 結果:NULL
🔑 試験ポイント:「NULLを含む計算は全部NULL」これは例外なく適用されます。NULL + 0 も NULL / 1 も、すべてNULLです。
文字列連結でのNULLの挙動
文字列連結演算子 || を使う場合、NULLは空文字として扱われ、もう一方の文字列がそのまま返ります。
SELECT NULL || 'Oracle' FROM DUAL; -- 結果:Oracle
SELECT 'Hello' || NULL FROM DUAL; -- 結果:Hello
SELECT NULL || NULL FROM DUAL; -- 結果:NULL(両方NULLのみNULLになる)
🔑 算術式と文字列連結でNULLの挙動が異なることは試験の頻出ポイントです。
操作 NULLが含まれる場合の結果 算術式( +,-,*,/)常にNULL 文字列連結( ||)相手の値がそのまま返る(両方NULLのみNULL)
NULL条件の指定方法
NULLの検索は、= や <> などの等価・比較条件では検索できません。
| 条件式 | 評価結果 | 説明 |
|---|---|---|
a IS NULL |
TRUE(aがNULLのとき) | NULLを検索する正しい方法 |
a IS NOT NULL |
TRUE(aがNULLでないとき) | NULLを除外する正しい方法 |
a = NULL |
UNKNOWN | 常にUNKNOWN → 結果は0件 |
a <> NULL |
UNKNOWN | 常にUNKNOWN → 結果は0件 |
a = '' |
UNKNOWN | OracleではNULLと同じ扱い → 結果は0件 |
WHEREの条件が UNKNOWN になった場合、その行は返されません(FALSE と同じ扱い)。
-- ✅ 正しい:NULLを検索する
SELECT * FROM test_null_distinct WHERE commission_pct IS NULL;
-- ✅ 正しい:NULLを除外する
SELECT * FROM test_null_distinct WHERE commission_pct IS NOT NULL;
-- ❌ 間違い:等価条件でNULLを検索しても0件
SELECT * FROM test_null_distinct WHERE commission_pct = NULL;
-- ❌ 間違い:空文字でもNULLは検索できない(OracleはNULL扱い)
SELECT * FROM test_null_distinct WHERE commission_pct = '';
🔑 試験ポイント:
= NULLや<> NULLは構文エラーにはなりません。エラーなく実行されるが、結果が0件になるという点が引っかけになります。
SQL*PlusでのNULL表示設定
SQL*Plusでは、NULL値はデフォルトで**何も表示されない(空白)**ため、見た目では判断しにくいです。SET NULL コマンドを使うことで、NULL値を視覚的に確認できます。
-- NULLの表示を "(null)" に変更する
SET NULL '(null)'
-- 元に戻す(何も表示しない)
SET NULL ''
💡
SET NULLはSQL*Plusの専用コマンドです。SQL文ではないため末尾に;は不要です。
DISTINCTによる重複データの除外
DISTINCTとは
DISTINCT は、SELECTの結果から重複した行を取り除くキーワードです。
SELECT DISTINCT 列名 FROM 表名;
基本的な使い方
-- 重複を除いた部署IDの一覧を取得
SELECT DISTINCT department_id
FROM test_null_distinct;
動作確認
テストデータ作成 実行例(イメージ)
| department_id(重複あり) | department_id(DISTINCT後) |
|---|---|
| 10 | 10 |
| 10 | 20 |
| 20 | 30 |
| 30 | NULL |
| NULL | |
| NULL |
複数列へのDISTINCT適用
複数列を指定した場合、列の組み合わせが重複しているかどうかを判定します。
-- 部署IDと役職IDの組み合わせで重複除去
SELECT DISTINCT department_id, job_id
FROM test_null_distinct ;
DISTINCTはSELECTリスト全体に適用されるため、SELECT DISTINCT col1, col2 のように書いた場合、(col1, col2) の組み合わせが重複しているかを判定します。
DISTINCTとNULLの関係
DISTINCT使用時、NULLも1つの値として扱われ、複数のNULLは1つにまとめられます。
-- NULLが複数あっても1件にまとめられる
SELECT DISTINCT commission_pct FROM test_null_distinct;
-- commission_pct が NULL の行が複数あっても、結果には NULL が1行だけ出る
COUNT(DISTINCT ...) の注意点
COUNT と DISTINCT を組み合わせるときは、NULLはカウントされない点に注意が必要です。
SELECT COUNT(DISTINCT department_id) FROM test_null_distinct;
-- department_id が NULL の行はカウントから除外される
DISTINCTを使う際のエラーに注意
ORDER BY句に、SELECTで指定していない列を使うとエラー(ORA-01791)になります。
-- ❌ エラー:SELECT に含まれていない列を ORDER BY に指定
SELECT DISTINCT department_id
FROM test_null_distinct
ORDER BY last_name; -- ORA-01791
-- ✅ 正しい:SELECTに含まれている列でORDER BY
SELECT DISTINCT department_id
FROM test_null_distinct
ORDER BY department_id;
本章のまとめ
| テーマ | 試験で押さえるポイント |
|---|---|
| NULLとは | 値が存在しない・不明な状態。0や空白とは異なる |
| 空文字とNULL | Oracleでは '' はNULLとして扱われる |
| 算術式 | NULLを含む計算は常にNULL |
| 文字列連結 | NULL || '文字列' は '文字列' になる(算術と異なる挙動) |
| NULL条件 |
IS NULL / IS NOT NULL を使う。= NULL は常にUNKNOWN(0件) |
| SET NULL | SQL*Plusコマンド。NULL値の表示形式を変更できる |
| DISTINCT | 重複行を除去。SELECT DISTINCT 列名 の形式で使う |
| DISTINCTと複数列 | 列の組み合わせ全体で重複判定する |
| DISTINCTとNULL | NULLも1値として扱われ、複数NULLは1件にまとめられる |
| COUNT(DISTINCT) | NULLはカウント対象外 |
| ORDER BY制限 | DISTINCTの場合、SELECTにない列でのORDER BYはエラー(ORA-01791) |
第2章の振り返り
第2章では以下を学びました。
| 節 | 内容 |
|---|---|
| 前編 | SELECT文の基本構文・書く順序と実行順序の違い |
| 前編 | データ型(VARCHAR2・NUMBER・DATE など)と表の確認方法 |
| 中編 | 算術演算子の種類と優先順位 |
| 中編 | 文字列・連結演算子・代替引用符 |
| 中編 | 日時データ・書式モデル・NLS_DATE_FORMAT |
| 後編 | NULLの性質と正しい扱い方 |
| 後編 | DISTINCTによる重複除去 |
次の章では、WHERE句の応用(BETWEEN・IN・LIKE)やORDER BYを扱います。
















