Table of Contents
SQLのCOALESCEとNULLIF、ちゃんと理解しておく
データベーススペシャリストの勉強中に COALESCE と NULLIF を整理した。試験で出たときにサッと読めるように自分用メモ。
COALESCE
引数を左から順に見て、最初に NULL じゃない値を返す関数。全部 NULL なら NULL。
COALESCE(A, B, C)| 式 | 結果 | 理由 |
|---|---|---|
COALESCE(NULL, NULL, '東京') | '東京' | 左から見て最初の非NULLは3番目 |
COALESCE('大阪', NULL, '東京') | '大阪' | 1番目がすでに非NULL |
COALESCE(NULL, NULL, NULL) | NULL | 全部NULLなのでNULL |
-- 携帯 → 自宅 → デフォルト値 の優先順位で連絡先を取得SELECT 社員名, COALESCE(携帯番号, 自宅番号, '番号なし') AS 連絡先FROM 社員;引数の並び順がそのまま優先順位になる。
NULLIF
2つの値が同じなら NULL、違えば第1引数をそのまま返す。
NULLIF(A, B)| 式 | 結果 | 理由 |
|---|---|---|
NULLIF(10, 10) | NULL | 同じ値 → NULL |
NULLIF(10, 5) | 10 | 違う値 → 第1引数 |
NULLIF(0, 0) | NULL | 同じ値 → NULL |
ゼロ除算の防止
SELECT 売上 / NULLIF(件数, 0) AS 平均売上FROM 売上表;- 件数 = 0 →
NULLIF(0, 0)→ NULL →売上 / NULL→ NULL(エラーにならない) - 件数 = 5 →
NULLIF(5, 0)→ 5 →売上 / 5→ 計算結果
CASE WHEN 件数 = 0 THEN NULL ELSE 売上 / 件数 END と同じことを1行で書ける。
空文字を NULL に統一
SELECT NULLIF(備考, '') AS 備考FROM テーブル;備考が '' なら NULL に、それ以外はそのまま返る。
組み合わせパターン
COALESCE と NULLIF の組み合わせ。空文字をスキップしてデフォルト値を設定する。
COALESCE(NULLIF(備考, ''), 'データなし')内側の NULLIF から先に評価される。
- 備考 =
''のときNULLIF('', '')→ NULLCOALESCE(NULL, 'データなし')→'データなし'
- 備考 =
'重要'のときNULLIF('重要', '')→'重要'COALESCE('重要', 'データなし')→'重要'
単純に COALESCE(備考, 'データなし') だけだと、空文字 '' は NULL じゃないのでそのまま通過してしまう。空文字も「値なし」として扱いたいときに NULLIF を噛ませる。
実践:LEFT JOIN で NULL が出るケース
LEFT JOIN で結合先にデータがない行は NULL になる。
SELECT e.社員名, COALESCE(d.部署名, '未配属') AS 部署名FROM 社員 eLEFT JOIN 部署 d ON e.部署ID = d.部署ID;| 社員名 | 部署ID | 部署名(JOIN結果) | COALESCE後 |
|---|---|---|---|
| 田中 | 1 | 営業部 | 営業部 |
| 鈴木 | 2 | 開発部 | 開発部 |
| 佐藤 | NULL | NULL | 未配属 |
複数テーブルを LEFT JOIN して最初に見つかった値を使うパターンもある。
-- 社員の連絡先を、個人情報 → 部署共有 → 会社代表 の優先順で取得SELECT e.社員名, COALESCE(p.メール, d.共有メール, c.代表メール) AS 連絡先メールFROM 社員 eLEFT JOIN 個人連絡先 p ON e.社員ID = p.社員IDLEFT JOIN 部署 d ON e.部署ID = d.部署IDLEFT JOIN 会社情報 c ON c.会社ID = 1;COALESCE の引数に複数テーブルのカラムを並べれば、NULL のカラムをスキップして次の候補に進む。
実践:集計関数が NULL を返す罠
SUM や MAX は、対象行が0件のとき NULL を返す。0 じゃない。
-- 該当データが0件だと NULL が返るSELECT SUM(金額) FROM 売上 WHERE 年月 = '2026-02';-- COALESCE で 0 をデフォルトにするSELECT COALESCE(SUM(金額), 0) AS 売上合計FROM 売上WHERE 年月 = '2026-02';COUNT だけは例外で、0件でも 0 を返す。
| 集計関数 | 対象行が0件のとき | 全行NULLのとき |
|---|---|---|
COUNT(*) | 0 | 行数を返す |
COUNT(列名) | 0 | 0 |
SUM | NULL | NULL |
AVG | NULL | NULL |
MAX / MIN | NULL | NULL |
サブクエリ内の集計を外側で使うパターン。
-- 各部署の今月売上を一覧表示(売上データがない部署も含む)SELECT d.部署名, COALESCE( (SELECT SUM(金額) FROM 売上 s WHERE s.部署ID = d.部署ID AND s.年月 = '2026-02'), 0 ) AS 今月売上FROM 部署 d;SUM が NULL を返しても COALESCE で 0 になる。
覚え方
- COALESCE → 左から最初の非NULL
- NULLIF → 同じなら NULL
参考
SQLのCOALESCEとNULLIF、ちゃんと理解しておく
https://p4ni.com/posts/coalesce-nullif/