SQLでNULL値を0や特定の数値で置き換える方法

結論:SQL Serverで検索結果のNULLを0に見せたいだけなら、ISNULL(列名, 0)またはCOALESCE(列名, 0)を使います。複数の候補から最初の非NULL値を返したい場合はCOALESCE、条件に応じて置換値を変えたい場合はCASEが分かりやすい方法です。元データ自体を0へ変更するにはUPDATEが必要ですが、NULLが「未入力」「不明」「対象外」のどれを表すか確認し、バックアップと対象件数の確認後に実行してください。SQL ServerではIFNULLは使えず、ISNULLがSQL Server固有の関数です。 最新の画面名や提供条件は更新で変わるため、以下の順番で確認してください。

目次

最初に確認するポイント

症状・条件主な原因最初の確認
IFNULLを実行すると関数が認識されないエラーになるIFNULLはMySQLなどで使われる関数で、SQL ServerのT-SQLにはありません。SQL ServerではISNULLまたはCOALESCEを使います。接続先DBMSがSQL Serverかを確認し、SELECT @@VERSION;で実行環境を確認します。
NULLを文字列へ置換したら文字が切れる、または型変換エラーになるISNULLは原則として第1引数のデータ型を返し、置換値がその型へ暗黙変換されます。COALESCEはデータ型の優先順位に従うため、混在する型で結果が変わります。対象列のデータ型と長さを確認し、置換値を明示的にCASTまたはCONVERTします。
AVGやCOUNTの結果がNULL置換前と変わったAVGなど多くの集計関数はNULLを無視しますが、NULLを0へ置換すると0の行も計算対象になります。COUNT(*)はNULLを含む行数を数え、COUNT(列)は非NULLだけを数えます。AVG(列)とAVG(COALESCE(列, 0))、COUNT(*)とCOUNT(列)を並べ、分母の違いを確認します。
SELECTでは0と表示されるのに、別の画面ではNULLのままISNULLやCOALESCEをSELECT句で使っても、保存データは変更されません。そのクエリ結果だけを置換して表示しています。要件が表示時の補完か、テーブルの永続更新かを決め、永続更新なら対象件数をSELECTで確認します。
COALESCEにサブクエリを入れると結果が安定しないことがあるSQL ServerではCOALESCEがCASEへ展開され、引数の式が複数回評価される場合があります。変動するサブクエリを直接入れると、同時更新の影響を受ける可能性があります。サブクエリの結果を派生表やAPPLYで一度だけ求めてから、ISNULLまたはCOALESCEへ渡します。

安全な対処手順

1. 表示だけの置換か、データ更新かを先に決める

レポートや画面でNULLを0として表示したいだけなら、SELECTでISNULLやCOALESCEを使うのが安全です。テーブルのNULLを恒久的に0へ書き換える必要がある場合だけUPDATEを検討します。NULLは0と同じ意味ではなく、未入力、不明、対象外を表すことがあるため、置換前に業務上の意味を確認してください。

  1. 表示・計算時だけ補完するならSELECTを使う
  2. 保存値を変更する要件がある場合だけUPDATEを使う
  3. NULL、0、空文字の業務上の意味を確認する
  4. NOT NULL制約やDEFAULTは今後の入力を制御するもので、既存NULLは別途処理する
SELECT @@VERSION;
SELECT COUNT(*) AS null_rows
FROM dbo.Sales
WHERE amount IS NULL;

注意:NULLを一律に0へ変えると、「不明」と「実績ゼロ」を区別できなくなります。

2. SQL ServerではISNULLで手早く置換する

SQL Serverで1つの列のNULLを固定値へ置き換えるなら、ISNULLが簡潔です。第1引数がNULLでなければその値を返し、NULLなら第2引数を返します。ISNULLの戻り値は原則として第1引数の型になるため、文字列の長さや数値の精度を固定したい場合は、置換前に明示的なCASTまたはCONVERTを入れます。

  1. 数値のNULLを0にする
  2. 文字列のNULLを表示用ラベルにする
  3. 戻り値の型と長さを明示する
SELECT ISNULL(amount, 0) AS amount
FROM dbo.Sales;
SELECT ISNULL(CAST(note AS nvarchar(100)), N'未登録') AS note
FROM dbo.Sales;

注意:第1引数が短い文字列型だと、長い置換文字列が切り詰められる場合があります。実データ型を確認してください。

3. 複数候補や移植性を重視するならCOALESCEを使う

COALESCEは左から順に評価し、最初の非NULL値を返します。複数列の優先順位を表現でき、標準SQLとして他のDBMSでも使いやすい点が利点です。SQL Serverでは、結果の型が引数のデータ型優先順位で決まるため、異なる型を混ぜる場合はCASTでそろえます。また、変動するサブクエリを引数へ直接書くと複数回評価される可能性があるため、先に結果を1列へ確定させてください。

  1. 第1候補、第2候補、既定値の順に並べる
  2. 数値と文字列など異なる型を混ぜない
  3. サブクエリは派生表やAPPLYで先に1回評価する
SELECT COALESCE(discount, campaign_discount, 0) AS effective_discount
FROM dbo.Sales;
SELECT COALESCE(CAST(primary_value AS decimal(18,2)),
                CAST(fallback_value AS decimal(18,2)),
                CAST(0 AS decimal(18,2))) AS effective_value
FROM dbo.SourceData;

注意:COALESCEとISNULLは似ていますが、戻り値の型、NULL許容性のメタデータ、評価回数が同じとは限りません。

4. 条件ごとに置換値を変えるならCASEを使う

売上額や評価値など別の列を見て置換値を変える場合は、検索CASEを使います。WHENの条件を上から評価し、最初に真となったTHENの値を返します。どの条件にも一致しない行を元の値に戻すならELSEへ対象列を書きます。条件が重なる場合は、優先順位の高い条件を先に置きます。

  1. NULLかつ売上1,000以上なら100を返す
  2. NULLかつ売上1,000未満なら50を返す
  3. NULLでなければ元の値を返す
SELECT CASE
         WHEN discount IS NULL AND total_sales >= 1000 THEN 100
         WHEN discount IS NULL AND total_sales < 1000 THEN 50
         ELSE discount
       END AS adjusted_discount
FROM dbo.Sales;

注意:ELSEを省略し、どの条件にも一致しなければ結果はNULLになります。

5. 元データを更新する場合はトランザクションで確認する

テーブルのNULLを恒久的に0へ変える場合は、先に対象件数と対象行をSELECTで確認し、バックアップまたは復旧手段を用意してからUPDATEします。トランザクション内で更新し、@@ROWCOUNTとサンプル行を確認したうえでCOMMITします。想定と違えばROLLBACKします。本番では、長時間ロックやログ増加を避けるため、件数に応じて実行時間と分割更新も検討してください。

  1. WHERE句でNULLの行だけを対象にする
  2. 更新前に件数と主キーを保存する
  3. トランザクション内で更新件数を確認する
  4. 確認できるまでCOMMITしない
BEGIN TRANSACTION;

SELECT COUNT(*) AS target_rows
FROM dbo.Sales
WHERE amount IS NULL;

UPDATE dbo.Sales
SET amount = 0
WHERE amount IS NULL;

SELECT @@ROWCOUNT AS updated_rows;

-- 内容を確認して問題なければ実行
-- COMMIT TRANSACTION;

-- 問題があれば実行
-- ROLLBACK TRANSACTION;

注意:UPDATEは元データを変更します。WHERE句なしの実行、確認前のCOMMIT、バックアップなしの一括更新は避けてください。

6. 集計ではNULLを0にする意味を確認する

SQL ServerのAVG、SUM、MIN、MAXなど多くの集計関数はNULLを無視します。AVG(amount)は値が入っている行だけを分母にしますが、AVG(COALESCE(amount, 0))は元がNULLの行も0として分母に含めます。どちらが正しいかは、NULLが未観測なのか実績ゼロなのかで変わります。COUNTも、COUNT(*)は全行、COUNT(amount)は非NULL行だけを数えます。

  1. NULLを除外した平均と0を含めた平均を比較する
  2. COUNT(*)とCOUNT(列)の違いを確認する
  3. 集計仕様をレポートの注記または設計書に残す
SELECT AVG(amount) AS avg_non_null,
       AVG(COALESCE(amount, 0)) AS avg_null_as_zero,
       COUNT(*) AS all_rows,
       COUNT(amount) AS non_null_rows
FROM dbo.Sales;

注意:見た目を整えるためだけに集計式のNULLを0へ変えると、KPIや請求値が変わる可能性があります。

よくある質問

SQL ServerでIFNULLは使えますか?

使えません。IFNULLはMySQLなどの関数です。SQL Serverでは、2つの値ならISNULL、複数候補や標準SQLとして書くならCOALESCE、条件ごとに値を変えるならCASEを使います。

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

SQL Serverだけで1列を固定値へ置換するならISNULLが簡潔です。複数の候補から最初の非NULL値を返したい場合や、他DBMSへの移植性を重視するならCOALESCEが向きます。ただし、戻り値の型、NULL許容性、式の評価回数が異なるため、重要な列ではCASTを明示してテストしてください。

NULLを0に置換すると平均値は変わりますか?

変わる場合があります。AVG(列)はNULLを無視しますが、AVG(COALESCE(列, 0))はNULLだった行を0として計算対象に含めます。NULLが未入力や不明を表すなら前者、実績ゼロとして扱う業務定義なら後者が合う可能性があります。定義を決めてから式を選んでください。

公式情報

画面や仕様が異なる場合は、利用中の製品・契約・管理ポリシーを確認したうえで公式情報を参照してください。

まとめ

原因を一つずつ切り分け、変更前の状態と結果を記録しながら進めることが重要です。操作後は同じ症状が再発しないか確認し、組織管理の端末ではポリシー変更を管理者へ確認してください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次