【2026年7月最新】SQLのNULL完全解説|IS NULL・ISNULL・COALESCE・NVLを業務データベースで使いこなす

【2026年7月最新】SQLのNULL完全解説|IS NULL・ISNULL・COALESCE・NVLを業務データベースで使いこなす

「SQLでNULLが絡むとうまく動かない」「IS NULLとISNULL関数の違いが分からない」「COALESCEとNVLはどう違うの?」——データベースを扱うようになると、NULLの壁に必ずぶつかります。NULLは「値がない」という状態を表す特殊な概念で、通常の値(0や空文字など)とは全く異なる扱いが必要です。この「特殊な扱い」を知らないまま進めると、検索結果が正しく出なかったり、集計値が予想外の数字になったりというバグが発生します。

この記事では、SQLのNULL処理を完全に解説します。IS NULL演算子によるNULL判定、IS NOT NULL、ISNULL関数・COALESCE関数・NVL関数・IFNULL関数の環境別使い分け、集計関数とNULLの落とし穴、CASE式を使った柔軟なNULL制御、そしてよくあるNULLバグのパターンと対策まで、業務データベースで即使えるレベルで整理していきます。

代表菅澤 代表菅澤
弊社では社内のデータ分析・売上集計・顧客管理をすべてSQLで回しています。NULLの扱いを間違えて「売上合計が実際より少なく出た」という経験があります。NULLは地味に見えて、集計クエリの正確性に直結する重要な概念です。
AI鬼管理山崎 AI鬼管理山崎
特にCOALESCE関数は「NULLを0に置換して集計する」業務では毎回使います。また「= NULLが効かない」という初歩的な罠は多くの方が一度踏むので、最初に仕組みを理解しておくことが大切です。

この記事を最後まで読むと、次のことが分かります。

✔️NULLの本質:0や空文字と何が違うのか、データベースでどう格納されるか
✔️IS NULL / IS NOT NULL:NULL判定の正しい書き方と=NULL比較がNGな理由
✔️ISNULL・COALESCE・NVL・IFNULL:環境ごとのNULL置換関数の使い分け完全マップ
✔️集計関数の落とし穴:COUNT(*)とCOUNT(列名)の違い、AVGがNULLを無視する仕組み
✔️CASE式のNULL制御:条件分岐でNULLを自在に扱うテクニック
✔️NULLバグのパターン:業務で頻出するNULL起因のバグと防御的コーディング
Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理
📌 この記事の結論
【2026年7月最新】SQLのNULL完全解説|IS NULL・ISNULL・COALESCE・NVLを業務データベースで使いこなす
SQLのNULL値の扱い方を完全解説。IS NULL/IS NOT NULL演算子、ISNULL・COALESCE・NVL・IFNULL関数の違いと使い分け、集計関数との罠、CASE式活用まで、業務DBで即使える実践ガイドです。

01 SQLのNULLとは何か――値が「存在しない」ことの意味 0・空文字との違い、三値論理、データベースでの格納の仕組み

SQLにおけるNULLとは、「値が存在しない・不明・適用不可能」という状態を表す特殊なマーカーです。数値の0や文字列の空文字("")とは全く別物です。たとえば顧客テーブルの「メールアドレス」列にNULLが入っているなら「メールアドレスを登録していない」ことを意味し、空文字""なら「登録はしたが中身が空」という違いになります。この区別がデータの正確性に直結します。

📚 用語解説

NULL(ヌル):SQLにおいてデータが「存在しない」「不明」「未入力」であることを表す特殊な値。数値の0や空文字""とは異なる概念です。NULLは「値が未定義」であることを示すため、通常の比較演算(=、<>)ではNULLを検出できず、専用のIS NULL演算子が必要になります。

NULLの最大の特徴は「通常の比較演算が効かない」点です。SQLでは「列 = NULL」という条件式は常にFALSEではなく、UNKNOWN(不明)という第3の状態を返します。これをSQLの「三値論理」と呼びます。WHERE句でUNKNOWNが返った行は結果セットに含まれません。「= NULL」でNULLを検出しようとすると何も返ってこないのは、この三値論理の仕組みによるものです。

📚 用語解説

三値論理(Three-valued logic):SQLの比較演算の結果がTRUE・FALSE・UNKNOWN(不明)の3種類になる論理体系。NULLが含まれる比較(NULL = 5、NULL = NULLなど)は常にUNKNOWNを返します。WHERE句でUNKNOWNになった行は結果から除外されます。これを知らずに「= NULL」でNULL検索すると、検索結果が0件になります。

NULLはデータベースのあらゆる場面に影響します。WHERE句での検索、JOIN結合、GROUP BYによる集計、ORDER BY並び替え——それぞれでNULLが特殊な挙動を示します。JOIN結合では、結合キーがNULLの行は一致なしとして扱われます。ORDER BYでは、多くのDBMSでNULLはASCの場合に最小値扱い(先頭または末尾)になります。こうした挙動を理解せずに業務SQLを書くと、意図しないデータの欠落や集計ミスが発生します。

比較対象NULLとの違い業務での典型例
数値の00は「ゼロという値が存在する」。NULLは「値自体が存在しない」売上0円 vs 売上未登録
空文字""""は「空の文字列という値が存在する」。NULLは「値がない」電話番号が空欄(登録済) vs 電話番号が未登録
スペース" "スペースは1文字の文字列。NULLは値の不在コード欄のスペース埋め vs 未入力
AI鬼管理山崎 AI鬼管理山崎
NULLと空文字の区別は、業務データの品質管理で非常に重要です。「電話番号がNULL」と「電話番号が空文字」を同一視すると、「連絡先未登録顧客」の件数が正確に出なくなります。

02 IS NULL演算子の使い方 NULL値の行を正確に検出するための唯一の正しい方法

IS NULL演算子は、列の値がNULLであることを判定するための演算子です。前のセクションで説明したように、「= NULL」は三値論理の問題で常にUNKNOWNを返すため使えません。NULLを検索したい場合は必ず「IS NULL」を使います。構文は「列名 IS NULL」で、その列がNULLであればTRUEを返します。

-- IS NULLの基本例
-- 顧客テーブルからメールアドレスが未登録の顧客を取得
SELECT
    customer_id,
    customer_name,
    phone_number
FROM
    customers
WHERE
    email IS NULL;

-- 複数条件と組み合わせる例(メールがNULL かつ 電話番号も入っている)
SELECT
    customer_id,
    customer_name
FROM
    customers
WHERE
    email IS NULL
    AND phone_number IS NOT NULL;

-- NG例:「= NULL」は使わない(常に0件が返る)
-- SELECT * FROM customers WHERE email = NULL;  -- 常に空結果
-- SELECT * FROM customers WHERE email <> NULL; -- 同様に空結果

2-1. IS NULLを使った実践的なクエリパターン

業務DBでIS NULLが最もよく使われるのは「データ不備の検出」です。入力フォームから登録されたデータに必須項目が漏れていないか確認する、バッチ処理で未処理レコードを抽出する、マスターデータとの結合で未紐付けレコードを洗い出す——こうした品質チェックのSQL全般でIS NULLが活躍します。

-- 実践パターン1:データ不備チェック(複数列のNULLを一括確認)
SELECT
    customer_id,
    customer_name,
    CASE WHEN email IS NULL THEN '未登録' ELSE '登録済' END AS email_status,
    CASE WHEN phone_number IS NULL THEN '未登録' ELSE '登録済' END AS phone_status,
    CASE WHEN address IS NULL THEN '未登録' ELSE '登録済' END AS address_status
FROM
    customers
WHERE
    email IS NULL
    OR phone_number IS NULL
    OR address IS NULL
ORDER BY
    customer_id;

-- 実践パターン2:LEFT JOINで結合できなかった行を抽出(孤立レコード検出)
SELECT
    o.order_id,
    o.customer_id
FROM
    orders o
    LEFT JOIN customers c ON o.customer_id = c.customer_id
WHERE
    c.customer_id IS NULL;  -- JOINできなかった = 顧客マスターに存在しない注文
💡 LEFT JOINでのIS NULLは「存在しない行の検出」に最適

テーブルAに存在するがテーブルBに存在しないレコードを探す処理は、LEFT JOIN + WHERE B.key IS NULLのパターンが定石です。NOT IN(サブクエリ)より直感的で、NULLを含む場合の挙動も安定しています。

代表菅澤 代表菅澤
弊社では月次の受注データ整合性チェックSQLをClaude Codeで自動生成させています。「顧客IDが顧客マスターに存在しない注文データを検出する」という要件を説明すると、LEFT JOIN + IS NULLのパターンを即座に生成してくれます。

03 IS NOT NULL演算子の使い方 NULL以外の行を抽出する逆条件と、NOTの位置に注意すべき点

IS NOT NULL演算子は、IS NULLの逆で「NULL以外の値が存在する」行を抽出します。「値が入力されているレコードだけ処理したい」「メールアドレスが登録済みの顧客にだけ送信する」といった場面で使います。構文は「列名 IS NOT NULL」で、値がNULLでなければTRUEを返します。「NOT (列名 IS NULL)」と等価です。

-- IS NOT NULLの基本例
-- メールアドレスが登録済みの顧客のみ取得
SELECT
    customer_id,
    customer_name,
    email
FROM
    customers
WHERE
    email IS NOT NULL;

-- 複数条件:電話・メール両方が入力済みの顧客
SELECT
    customer_id,
    customer_name
FROM
    customers
WHERE
    email IS NOT NULL
    AND phone_number IS NOT NULL;

-- 注文に対して担当者が割り当てられているもの
SELECT
    order_id,
    order_date,
    assigned_staff
FROM
    orders
WHERE
    assigned_staff IS NOT NULL
ORDER BY
    order_date DESC;

3-1. IS NOT NULLとNULL排除の考え方

業務クエリで重要なのは、集計・分析系のSQLでNULLを意図的に排除するかどうかを明示的に決断することです。たとえば「登録済みメールアドレスの件数」を集計するとき、WHERE email IS NOT NULL を付けるかどうかで結果が変わります。後述するCOUNT関数の挙動と合わせて理解することが重要です。

-- NULL排除の集計例
-- 全顧客数
SELECT COUNT(*) AS total_customers FROM customers;

-- メール登録済みの顧客数(IS NOT NULLで明示的に絞り込む)
SELECT COUNT(*) AS email_registered_count
FROM customers
WHERE email IS NOT NULL;

-- 上記と同等だが、COUNT(email)でも同じ結果(NULLは自動除外される)
SELECT COUNT(email) AS email_registered_count
FROM customers;

-- メール未登録率の計算
SELECT
    COUNT(*) AS total,
    SUM(CASE WHEN email IS NULL THEN 1 ELSE 0 END) AS null_count,
    ROUND(
        SUM(CASE WHEN email IS NULL THEN 1 ELSE 0 END) * 100.0 / COUNT(*),
        1
    ) AS null_rate_percent
FROM customers;
AI鬼管理山崎 AI鬼管理山崎
IS NOT NULLはWHERE句でよく使いますが、CASE式との組み合わせでNULL率の計算ができます。「必須項目の入力率レポート」のようなデータ品質ダッシュボードを作るとき重宝するパターンです。
✔️NULL行を抽出したい:WHERE 列名 IS NULL
✔️NULL以外を抽出したい:WHERE 列名 IS NOT NULL
✔️「= NULL」「<> NULL」は使用禁止(三値論理でUNKNOWNになる)
✔️NOT IN(サブクエリ)をNULL含みデータに使うと全件除外される危険がある(Section 07参照)
Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理

04 NULL置換関数の完全比較(ISNULL・COALESCE・NVL・IFNULL) 環境(SQL Server・Oracle・MySQL・PostgreSQL)ごとの使い分けマップ

NULL値が含まれる列を集計や表示に使う場合、NULLを別の値(0や空文字など)に置換してから処理するのが基本です。この「NULL置換」の関数はDBMSによって異なります。SQL ServerはISNULL関数、OracleはNVL関数、MySQLはIFNULL関数、そして全DBMSで使えるのがCOALESCE関数です。環境ごとに使う関数が違うため、複数のDBを扱う場面では混乱しやすい部分です。

関数名対応DBMS構文特徴
ISNULL()SQL Server(主)ISNULL(列, 代替値)引数2つのみ。高速だがSQL Server専用
NVL()Oracle(主)NVL(列, 代替値)引数2つのみ。Oracle専用
IFNULL()MySQL / MariaDBIFNULL(列, 代替値)引数2つのみ。MySQL系専用
COALESCE()全DBMS(SQL標準)COALESCE(値1, 値2, ...)引数N個。最初の非NULL値を返す。移植性◎
NVL2()OracleNVL2(列, NULL以外の値, NULLの値)NULL・非NULLで異なる値を返す高機能版

📚 用語解説

COALESCE(コアレス)関数:SQL標準で規定されたNULL置換関数。COALESCE(値1, 値2, ..., 値N)の形で複数の引数を取り、左から順に評価して最初のNULL以外の値を返します。全ての引数がNULLの場合のみNULLを返します。SQL Server・Oracle・MySQL・PostgreSQLすべてで使えるため、移植性を重視するときの第一選択です。

4-1. COALESCE関数の使い方(全環境対応)

-- COALESCE関数の基本例
-- 1つの列のNULLを0に置換
SELECT
    product_id,
    product_name,
    COALESCE(discount_rate, 0) AS discount_rate  -- NULLなら0に置換
FROM
    products;

-- 複数列を順に試す(最初に非NULLの列を使う)
SELECT
    customer_id,
    COALESCE(mobile_phone, home_phone, work_phone, '連絡先なし') AS contact_number
FROM
    customers;
-- mobile_phone→home_phone→work_phoneの順に非NULLの最初の値を使う

-- 集計でNULLを0として扱う(最重要パターン)
SELECT
    department,
    SUM(COALESCE(sales_amount, 0)) AS total_sales
FROM
    sales
GROUP BY
    department;

4-2. ISNULL関数(SQL Server)

-- SQL ServerのISNULL関数
-- 構文:ISNULL(確認する値, NULLの場合の代替値)
SELECT
    employee_id,
    employee_name,
    ISNULL(department, '未配属') AS department,
    ISNULL(bonus_amount, 0) AS bonus_amount
FROM
    employees;

-- COALESCE vs ISNULL の違い(SQL Server)
-- ISNULLは引数2つのみ。複数フォールバックが必要なときはCOALESCEを使う
SELECT
    ISNULL(col1, 'default')     -- OK: 引数2つ
    -- ISNULL(col1, col2, 'default') -- NG: 引数3つはエラー
    COALESCE(col1, col2, 'default') -- OK: 引数N個
FROM test_table;

4-3. NVL関数(Oracle)

-- OracleのNVL関数
-- 構文:NVL(確認する値, NULLの場合の代替値)
SELECT
    employee_id,
    NVL(department_name, '未配属') AS department_name,
    NVL(salary, 0) AS salary
FROM
    employees;

-- NVL2関数(NULL・非NULLで異なる値を返す高機能版)
-- 構文:NVL2(列, NULLでない場合の値, NULLの場合の値)
SELECT
    customer_id,
    NVL2(email, 'メール登録済', 'メール未登録') AS email_status
FROM
    customers;
-- emailがNULLでなければ'メール登録済'、NULLなら'メール未登録'を返す

4-4. IFNULL関数(MySQL / MariaDB)

-- MySQLのIFNULL関数
-- 構文:IFNULL(確認する値, NULLの場合の代替値)
SELECT
    product_id,
    product_name,
    IFNULL(stock_quantity, 0) AS stock_quantity,
    IFNULL(category, '未分類') AS category
FROM
    products;

-- MySQLではCOALESCEも使えるため、複数フォールバックが必要な場合はCOALESCEを推奨
SELECT
    COALESCE(mobile_phone, home_phone, '連絡先なし') AS contact
FROM customers;
💡 移植性を考慮するなら常にCOALESCEを使う

ISNULL・NVL・IFNULLはそれぞれ特定のDBMS専用関数です。将来的にDBを移行する可能性がある、または複数DBに対応したアプリケーションを作る場合は、SQL標準のCOALESCEに統一することを強く推奨します。引数が2つの場合もCOALESCE(列, 代替値)と書けば、どのDBMSでもそのまま動きます。

代表菅澤 代表菅澤
弊社ではSQL ServerからMySQLへのDB移行プロジェクトで、ISNULL関数をCOALESCEに一括置換する作業が発生しました。最初からCOALESCEで統一していれば不要な作業でした。この教訓から、社内では移植性を考慮してCOALESCE推奨にしています。

05 集計関数とNULL――COUNT・SUM・AVGの落とし穴 NULLを含むデータの集計で起きる「サイレントバグ」を防ぐ

SQLの集計関数はNULLを特別に扱います。集計関数の多くは「NULLを無視して集計する」という仕様になっていますが、この仕様が原因で意図せずデータが欠落するバグが発生します。「サイレントバグ」と呼ばれるこの問題は、結果が明らかにおかしくなるのではなく「数値が少し少ない」程度なので気づきにくく、業務データの信頼性を損なう原因になります。

関数NULLの扱い注意点
COUNT(*)全行をカウント(NULLも含む)テーブルの全行数を返す
COUNT(列名)NULLを除いてカウント列にNULLが含まれると COUNT(*) と異なる結果になる
SUM(列名)NULLを無視して合算全行NULLの場合はSUM=NULL(0ではない)
AVG(列名)NULLを除いた行数で割るNULLを「0」と混同すると平均値が変わる
MAX/MIN(列名)NULLを無視して最大・最小NULLは比較から除外される

📚 用語解説

COUNT(*) と COUNT(列名) の違い:COUNT(*)はNULLを含む全行を数えます。COUNT(列名)は指定した列がNULLでない行だけを数えます。顧客テーブルに100行あってemailが20行NULLの場合、COUNT(*) = 100、COUNT(email) = 80 になります。この違いを知らずに件数集計すると正確な数値が出ません。

-- COUNT(*)とCOUNT(列名)の違い
-- サンプルデータ: 顧客5人、メール登録3人(2人はNULL)
SELECT
    COUNT(*) AS total_rows,           -- 5(全行)
    COUNT(email) AS email_count,      -- 3(NULLを除く)
    COUNT(DISTINCT email) AS unique_emails  -- 重複除いたメール数
FROM customers;

-- SUMとAVGのNULL挙動
-- sales_amountに NULL が含まれる場合
SELECT
    SUM(sales_amount) AS total_sales,     -- NULLを無視して合算
    AVG(sales_amount) AS avg_sales,       -- NULLを除いた件数で割る
    COUNT(sales_amount) AS sales_count,   -- NULLを除いた件数
    COUNT(*) AS all_count                 -- 全件(NULL含む)
FROM monthly_sales;
-- NULLを「0」と見なしたAVGを計算したい場合
SELECT AVG(COALESCE(sales_amount, 0)) AS avg_with_zero FROM monthly_sales;

5-1. AVGのNULL罠:ゼロとNULLの混同

業務で最も誤解が多い集計関数がAVG(平均)です。AVGはNULLを除いた行数で合計値を割るため、「売上未登録(NULL)=売上ゼロ」とは異なる意味になります。売上が5件あって3件は売上金額が入力済み(10万・20万・30万)、2件はNULLの場合、AVGは(10+20+30)/3 = 20万円となります。もし2件のNULLを「0円の取引」として計算したいなら、COALESCE(sales_amount, 0)でゼロ置換してからAVGを取る必要があります。この区別を意識しているかどうかで、集計レポートの精度が変わります。

-- AVGのNULL vs COALESCE(0)の違い
SELECT
    AVG(sales_amount) AS avg_ignore_null,       -- NULLを除外して平均
    AVG(COALESCE(sales_amount, 0)) AS avg_zero  -- NULLを0として平均
FROM sales;

-- 例: [10万, 20万, 30万, NULL, NULL] の場合
-- avg_ignore_null = (10+20+30) / 3 = 20万
-- avg_zero       = (10+20+30+0+0) / 5 = 12万
-- ビジネス要件に合わせてどちらを使うか判断する必要がある
⚠️ 集計レポートのNULL罠:「少ない」ことに気づかない

SUM・AVG・COUNTがNULLを無視することで、集計値が実際より少なくなるケースがあります。「売上合計が先月より少ない」と思ったらデータ入力漏れ(NULL)が原因だった、というパターンは業務でよく発生します。集計クエリを書く際は、NULLがあることを前提に「NULLをどう扱うか」を明示的に設計してください。

AI鬼管理山崎 AI鬼管理山崎
集計SQLのレビューでよく見る問題が「COUNT(*)で件数を出しているが実は意図はメール登録済み件数だった」というケース。COUNT(*)とCOUNT(email)は結果が違います。集計関数の引数に列名を入れるか*にするかは、必ず意図を持って選んでください。

06 CASE式でNULLを柔軟に制御する NULL判定・条件分岐・ラベル置換を一気に実現するテクニック

CASE式はSQLの条件分岐構文で、NULLの扱いにも強力に活用できます。IS NULLとCASEを組み合わせると「NULLなら〇〇、値があれば〇〇、値が△△なら〇〇」という複雑なラベル置換や分類処理を1つのSQLで実現できます。COALESCE関数では表現できない「NULL以外の値にも条件を付けたい」ケースで、CASE式が威力を発揮します。

-- CASE式でNULLをラベル化する
SELECT
    customer_id,
    customer_name,
    CASE
        WHEN email IS NULL THEN 'メール未登録'
        WHEN email LIKE '%@gmail.com' THEN 'Gmail'
        WHEN email LIKE '%@yahoo.co.jp' THEN 'Yahoo'
        ELSE 'その他のメール'
    END AS email_category
FROM customers;

-- NULL・値の大小・特定値を組み合わせた分類
SELECT
    order_id,
    order_amount,
    CASE
        WHEN order_amount IS NULL THEN '金額未入力'
        WHEN order_amount = 0 THEN 'ゼロ円'
        WHEN order_amount < 10000 THEN '小額'
        WHEN order_amount < 100000 THEN '中額'
        ELSE '大口'
    END AS amount_category
FROM orders;

6-1. NULLIF関数:特定の値をNULLに変換する

NULLIF(値1, 値2)は、値1と値2が等しければNULLを返し、異なれば値1をそのまま返す関数です。ゼロ除算エラーを防ぐ際によく使われます。たとえば「売上合計 / 件数」を計算するとき、件数が0の場合にゼロ除算エラーが発生しますが、NULLIF(件数, 0)とすることで件数が0のときにNULLを返し、ゼロ除算を回避できます。

-- NULLIF関数:ゼロ除算エラーの防止
-- NG例: order_countが0のときゼロ除算エラー
-- SELECT total_amount / order_count FROM summary;

-- OK例: NULLIFでゼロをNULLに変換してからCOALESCEで最終結果
SELECT
    total_amount,
    order_count,
    COALESCE(total_amount / NULLIF(order_count, 0), 0) AS avg_amount
FROM
    monthly_summary;

-- NULLIFのもう一つの使い方:特定の文字列をNULLに変換
-- 例:'N/A' や 'なし' が入っているデータをNULLとして扱いたい
SELECT
    customer_id,
    NULLIF(company_name, 'N/A') AS company_name,  -- N/AをNULLに変換
    NULLIF(remarks, '') AS remarks                  -- 空文字をNULLに変換
FROM customers;

📚 用語解説

NULLIF関数:NULLIF(値1, 値2)は値1と値2が等しいときNULLを返し、異なるとき値1を返します。ゼロ除算の防止に最もよく使われます。NULLIF(件数, 0)と書くことで件数が0のときNULLに変換され、NULLを分母にした除算はエラーではなくNULLを返すため安全です。COALESCEと組み合わせてNULLをデフォルト値に置換するパターンが定石です。

NULL判定
IS NULL /
IS NOT NULL
NULL置換
COALESCE /
ISNULL / NVL
条件分岐
CASE IS NULL
THEN...
値→NULL変換
NULLIF(
値, 変換条件)
集計
COALESCE(AVG(),0)
COUNT(*) vs COUNT(列)
代表菅澤 代表菅澤
CASE式はNULLだけでなく業務ロジック全般に使える強力な構文です。「ステータスコードを日本語ラベルに変換する」「売上ランクをA/B/Cに分類する」といった処理も全部CASE式1つで書けます。Claude Codeに「このデータ変換ロジックをSQLで書いて」と言うと、CASE式を使った最適な形で書いてくれます。
Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理

07 NULLに関するよくある罠とバグパターン 業務SQLで頻出するNULL起因のバグと防御的コーディング

NULLは「見えないバグ」を生みやすい概念です。クエリが正常終了していても結果が不正確だったり、検索が意図通りに機能していなかったりという問題が発生します。ここでは業務SQLで頻出するNULL起因のバグパターンと、その防御的対処法を整理します。

7-1. NOT INとNULL:全件除外の罠

最も危険なNULLバグの1つが「NOT IN(サブクエリ)にNULLが含まれると全件除外される」問題です。NOT INは内部的に「列 <> 値1 AND 列 <> 値2 AND ...」に展開されますが、サブクエリの中にNULLが1件でも含まれると、「列 <> NULL」の比較がUNKNOWNになり、全行がWHERE条件を満たさなくなって0件が返ります。これは多くの開発者が最初に経験する重大なバグです。

-- NOT INにNULLが含まれると全件除外される罠
-- blacklistテーブルのcustomer_idにNULLが1件含まれているとする

-- NG:blacklistにNULLが含まれると0件が返る
SELECT customer_id FROM customers
WHERE customer_id NOT IN (SELECT customer_id FROM blacklist);
-- customer_id NOT IN (..., NULL) → 全行がUNKNOWNになり0件

-- OK①:サブクエリでNULLを除外してからNOT IN
SELECT customer_id FROM customers
WHERE customer_id NOT IN (
    SELECT customer_id FROM blacklist
    WHERE customer_id IS NOT NULL  -- NULLを除外!
);

-- OK②:NOT EXISTSに書き換える(NULLの影響を受けない)
SELECT c.customer_id FROM customers c
WHERE NOT EXISTS (
    SELECT 1 FROM blacklist b
    WHERE b.customer_id = c.customer_id
);
⚠️ NOT IN(サブクエリ)はNULL混入で全件除外になる

NOT IN(サブクエリ)を使う場合は、サブクエリのNULLを必ずIS NOT NULLで除外するか、NOT EXISTSに書き換えてください。「NULLが混入したとき」だけ全件が消えるため、テスト環境では気づかず本番で問題が発生するケースがあります。

7-2. NULLを含む算術演算:結果が全部NULL

NULLを含む算術演算(加算・減算・乗算・除算)の結果は全てNULLになります。「月次売上 + 前月繰越」を計算するとき、どちらかがNULLなら合計もNULLになります。集計レポートで「合計が出ない」という問題の多くはこれが原因です。算術演算の前にCOALESCEでNULLを0に置換するのが基本的な対処法です。

-- NULLを含む算術演算の罠
SELECT
    10 + NULL,   -- → NULL(10ではない)
    NULL * 5,    -- → NULL(0ではない)
    NULL / 2,    -- → NULL
    NULL + NULL  -- → NULL

-- 実務での防御的計算
SELECT
    order_id,
    COALESCE(base_amount, 0) + COALESCE(tax_amount, 0) AS total_amount
FROM orders;
-- どちらかがNULLでも0として計算される

7-3. JOINのNULL:結合キーがNULLの行は必ず除外

INNER JOINでもLEFT JOINでも、結合キー(ON句の条件)がNULLの行は「一致なし」として扱われます。顧客テーブルのcustomer_idがNULLの行は、注文テーブルとJOINしても結合されません。「LEFT JOINなのに結果が少ない」と感じるケースの原因として、結合キーのNULLが挙げられます。

-- JOINとNULLの挙動確認
-- NULL = NULLはFALSEではなくUNKNOWNのため、
-- NULLのキー同士は結合されない

SELECT
    c.customer_id,
    c.customer_name,
    o.order_id
FROM
    customers c
    LEFT JOIN orders o ON c.customer_id = o.customer_id
WHERE
    c.customer_id IS NOT NULL;  -- NULLキーを明示的に除外する防御策

-- NULLキーの存在確認
SELECT COUNT(*) AS null_key_count
FROM customers
WHERE customer_id IS NULL;
✔️NOT IN(サブクエリ):サブクエリのNULLをIS NOT NULLで必ず除外する
✔️算術演算:COALESCE(列, 0)でNULLをゼロに置換してから計算
✔️JOIN結合キー:NULLキーが含まれると結合されない(事前にIS NOT NULLで確認)
✔️WHERE条件:NULLを除外したい場合はIS NOT NULLを明示的に書く
✔️ORDER BY:NULLの並び順はDBMSによって異なる(NULLS FIRST/LAST で制御)
AI鬼管理山崎 AI鬼管理山崎
NOT INにNULLが混入するバグは、テストデータにNULLがない場合は気づかずに本番で初めて問題が発覚するケースが多いです。NOT INを使う際は必ずIS NOT NULLをサブクエリに入れる、またはNOT EXISTSに書き換えることをルール化することをお勧めします。

08 Claude CodeでSQLクエリを自動生成する NULLを考慮した堅牢なSQLをAIに生成させる実践ガイド

ここまでNULLに関する様々な知識を解説してきました。これらを毎回正確に実装するのは、特にSQLに慣れていない非エンジニアの方には大変です。弊社(株式会社GENAI)では、Claude CodeへのSQL自動生成を活用することで、NULL処理を含む複雑な集計クエリを正確かつ高速に生成しています。

Claude Codeにはデータベース関連の幅広い知識が組み込まれており、「どのDBMSを使っているか」「NULLをどう扱いたいか」を説明するだけで、COALESCE・IS NULL・CASE式を組み合わせた堅牢なSQLを生成してくれます。SQL設計の経験が浅いメンバーでも、AIが生成したSQLを読み解くことで実力が身につく効果もあります。

代表菅澤 代表菅澤
弊社では毎月の売上分析・顧客フィルタリング・データ品質チェックのSQLをほぼ全てClaude Codeで生成しています。「NULLを0として扱って部門別の平均売上を出したい」と伝えると、COALESCE + AVGの組み合わせを正確に書いてくれます。
✔️使っているDBMS(SQL Server・MySQL・Oracle・PostgreSQL)を伝える
✔️「NULLをゼロとして扱う」「NULLを除外して集計する」など、NULLの扱い方を明示する
✔️「NOT INではなくNOT EXISTSで書いて」など、バグを避けたい場合は方針を指示する
✔️生成されたSQLのコメントを読んで、NULLへの配慮がどこに入っているか確認する
✔️「このSQLにNULL処理の問題点があれば教えて」とレビューを依頼することもできる
💡 Claude CodeへのSQL依頼テンプレート

「MySQLを使っています。ordersテーブル(order_id, customer_id, amount, status)から、statusがNULLか"キャンセル"の注文を除外して、customer_idごとにamountを合計するSQLを書いてください。amountがNULLの場合は0として合計に含めてください。」このように、DBMS・対象テーブル・NULLの扱い方を含めて伝えると、正確なSQLが生成されます。

Claude Codeを使ったSQL自動生成のもう一つのメリットは「SQLレビュー機能」です。既存のSQLを貼り付けて「NULLの扱いに問題がないか確認して」と依頼すると、NOT IN(サブクエリ)のNULL問題や、AVGのゼロ置換漏れなど、潜在的なバグを指摘してくれます。業務クリティカルな集計SQLの品質向上に活用できます。

AI鬼管理山崎 AI鬼管理山崎
弊社のデータアナリストが書いたSQLをClaude Codeにレビューさせたところ、NOT INのNULL問題を含む潜在バグが3件発見されました。本番データでは問題なく動いていましたが、データが増えてNULLが混入した瞬間に問題が顕在化していたでしょう。定期的なSQLレビューにもAIを活用することをお勧めします。

09 まとめ SQLのNULL処理を完全にマスターするためのポイント整理

この記事では、SQLのNULL値の扱い方を8つのセクションで体系的に解説しました。NULL処理はSQLの中でも「知らないと静かにバグが出る」領域であり、一度正確に理解することで業務クエリの品質が大幅に向上します。

✔️NULLは0・空文字とは別物。「値が存在しない」ことを表す特殊なマーカー
✔️「= NULL」はNG。NULL判定には必ずIS NULL・IS NOT NULLを使う(三値論理の仕組み)
✔️NULL置換はCOALESCE推奨(全DB対応)。SQL Server=ISNULL、Oracle=NVL、MySQL=IFNULL
✔️COUNT(*)は全行、COUNT(列名)はNULLを除いた件数。集計の意図に合わせて使い分ける
✔️AVGはNULLを無視して割る。ゼロとして扱いたいならCOALESCE(列, 0)で置換してからAVG
✔️NOT IN(サブクエリ)にNULLが混入すると全件除外。IS NOT NULL除外またはNOT EXISTSに書き換える
✔️NULLIF関数でゼロ除算を防止。NULLを含む算術演算は全てNULLになることを意識する

NULLを正確に扱えるSQLは、データ品質と分析精度に直結します。「なぜかデータが少ない」「集計値が期待と違う」という問題の多くはNULLの誤った取り扱いが原因です。この記事で紹介したパターンを実務に取り入れることで、こうした問題を事前に防げるようになります。

また、Claude Codeを活用することで、NULLを考慮した堅牢なSQLを自動生成・レビューできます。弊社(株式会社GENAI)では、データ活用・業務自動化の設計支援を「AI鬼管理」として提供しています。SQL設計やデータ品質の改善についても、無料相談でご相談いただけます。

代表菅澤 代表菅澤
NULLの知識は「知ってるだけで実務の精度が変わる」代表的な領域です。今日学んだIS NULL・COALESCE・NOT EXISTSのパターンを、次に書くSQLから意識的に使ってみてください。

SQLとデータ活用の自動化を、AI鬼管理が一緒に設計します

「業務データの集計や分析をSQLで自動化したい」「既存のSQLにNULL処理の不備がないか確認したい」という方に向けて、弊社ではClaude Codeを活用したデータ活用・SQL設計の支援を行っています。

AI鬼管理山崎 AI鬼管理山崎
「SQLは何となく書けるが、NULLや複雑な結合に自信がない」という方も歓迎です。まずは無料相談で現状の課題をお聞かせください。最短で成果が出るデータ活用の仕組みをご提案します。

NEXT STEP

この記事の内容を、あなたのビジネスで
実践してみませんか?

AI活用を自社で回せるようになりたい方へ

AI鬼管理

Claude Code・Cowork導入支援から業務設計・社内浸透まで実践ベースで伴走。「自社で回せる組織」を90日で作る経営者向けトレーニング。

よくある質問

Q. SQLで「= NULL」と書くとなぜ動かないのですか?

A. SQLは三値論理(TRUE・FALSE・UNKNOWN)を採用しており、NULLを含む比較演算は常にUNKNOWNを返します。WHERE句でUNKNOWNになった行は結果から除外されるため、「= NULL」は常に0件が返ります。NULLを検索するには専用のIS NULL演算子を使ってください。

Q. COALESCEとISNULLはどちらを使えばいいですか?

A. COALESCE推奨です。COALESCE(列, 代替値)はSQL標準で全てのDBMS(SQL Server・MySQL・Oracle・PostgreSQL)で動きます。ISNULLはSQL Server専用関数のため、DBを移行する可能性がある場合や複数環境に対応したSQLを書く場合はCOALESCEに統一するのが安全です。

Q. COUNT(*)とCOUNT(列名)の違いは何ですか?

A. COUNT(*)はNULLを含む全行を数えます。COUNT(列名)はその列がNULLでない行だけを数えます。例えば10行あってemailが3行NULLの場合、COUNT(*) = 10、COUNT(email) = 7 になります。集計の意図(全件数 vs 入力済み件数)に合わせて使い分けてください。

Q. NULLのデータをJOINしても結合されないのはなぜですか?

A. ON句の結合条件でNULLが関与する比較は三値論理によりUNKNOWNになるため、結合条件が成立しません。つまり結合キーがNULLの行は、INNER JOINはもちろん、LEFT JOINでも結合相手を見つけられません。NULLのキーが含まれるデータをJOINする場合は、事前にIS NOT NULLでNULLを除外するか、COALESCE(key, -1)のようにNULL以外の値に変換する設計が必要です。

Q. NOT IN(サブクエリ)を使うと全件除外されることがあるのはなぜですか?

A. NOT INはサブクエリの全値と「<> 比較」を行います。サブクエリの結果にNULLが1件でも含まれると「列 <> NULL」の評価がUNKNOWNになり、全ての行がWHERE条件を満たさなくなります。対策は①サブクエリにWHERE 列 IS NOT NULLを追加する、②NOT EXISTSに書き換える、のどちらかです。

Q. AVGを計算するとNULLが含まれる行は無視されますか?

A. はい、AVGはNULLを除いた行のみで計算します。5行あって2行がNULLの場合、残り3行の値の合計を3で割った値が返ります。NULLを「0として計算した平均」を求めたい場合は、AVG(COALESCE(列名, 0))と書いてください。どちらの意味で平均を出したいかはビジネス要件によって異なります。

Q. SQLのNULL処理が複雑すぎて自分で書けないのですが、AIで自動生成できますか?

A. できます。Claude Codeに対して「MySQLで使っています。NULLをゼロとして集計したい」などDBMSと要件を伝えると、COALESCE・IS NOT NULL・CASE式を組み合わせたNULL処理済みのSQLを生成してくれます。また既存のSQLを貼り付けて「NULL処理に問題がないか確認して」とレビューを依頼することもできます。

AIAI鬼管理

AI鬼管理へのお問い合わせ

この記事を読んで気になった方へ。
AI鬼管理の専門スタッフが、御社に最適な
業務自動化プランを無料でご提案します。

会社名を入力してください
業種を選択してください
お名前を入力してください
正しいメールアドレスを入力してください

1つ以上選択してください
1つ以上選択してください
月額コストを選択してください

約1時間のオンライン面談(Google Meet)です

空き枠を取得中...
面談日時を選択してください

予約確定後、Google Calendarの招待メールをお届けします。
しつこい営業は一切ございません。

監修 最終更新日: 2026年7月19日
菅澤孝平
菅澤 孝平 株式会社GENAI 代表取締役
  • AI業務自動化サービス「AI鬼管理」を運営 — Claude Code を活用し、経営者の業務を「AIエージェントに任せる仕組み」へ転換するパーソナルトレーニングを 伴走構築 で提供。日報・採用・問い合わせ対応・経費精算・議事録・データ集計・営業リスト等の定型業務を、AIに代行させる体制を経営者と一緒に作り込む
  • Claude Code 実装ノウハウを 経営者・法人クライアント に直接指導。生成AIを「便利ツール」ではなく 「業務を任せる存在」 として運用する手法を体系化
  • 「やらせ切る管理」メソッドの開発者。シンゲキ株式会社(2021年設立・鬼管理専門塾運営)にて累計3,000名以上の学習者を志望校合格に導いた管理メソッドを、AI × 経営者支援 に転用
  • 著書『3カ月で志望大学に合格できる鬼管理』(幻冬舎)、『親の過干渉こそ、最強の大学受験対策である。』(講談社)
  • メディア出演: REAL VALUE / カンニング竹山のイチバン研究所 / ええじゃないかBiz 他
  • 明治大学政治経済学部卒
現在は AI鬼管理(Claude Code活用の伴走型パーソナルトレーニング)を主事業とし、経営者と二人三脚で「AIに業務を任せる仕組み」を実装。「実行を強制する環境」を AI で構築する手法を、自社の実運用知見をもとに発信している。