コマンド道場
NULL を扱う関数難易度 ★★★★

未登録と 0 件を正しく表示する

すべての顧客について「顧客名, 都道府県, 受注件数」を出してください。都道府県(pref)が未登録の顧客は「未登録」と表示します。受注件数は取消されていない受注(status が 'done')だけを数え、1 件も無い顧客は 0 と表示します。顧客番号(kokyaku_id)の小さい順に並べてください。

主要 7 製品で通用 そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server / Oracle Database / IBM Db2

製品ごとの対応表(実測)を見る

  • COALESCE は引数を左から見て、最初に NULL でない値を返します。
  • NVL(Oracle)や ISNULL(SQL Server)といった独自の関数もありますが、COALESCE なら書き換えずに済みます。
  • count(列) は NULL を数えません。LEFT JOIN で相手がいなかった行を 0 と数えたいときに効いてきます。
● 起動中…

この問題で使えるテーブル(名前をタップすると入力できます)

10

NULL
🔑int不可
int不可
date不可
text不可
データを見る(先頭 5 行)
juchu_idkokyaku_idjuchu_onstatus
100112025-11-05done
100222025-11-18done
100312025-12-02done
100432025-12-09cancel
100542025-12-24done

17

NULL
🔑int不可
🔑int不可
int不可
int不可
numeric(10,0)不可
データを見る(先頭 5 行)
juchu_idgyo_noshohin_idsuryotanka
10011120180
10012230120
100214223800
100225118500
10031644200

5

NULL
🔑int不可
text不可
text
date不可
データを見る(先頭 5 行)
kokyaku_idkokyaku_nameprefcreated_on
1青葉工業東京都2024-05-10
2白樺物産大阪府2024-08-01
3黒松システム東京都2025-01-15
4赤坂商会NULL2025-03-20
5三田商事愛知県2025-06-01

7

NULL
🔑int不可
text不可
text不可
numeric(10,0)不可
データを見る(先頭 5 行)
shohin_idshohin_namecategoryprice
1ノート文具180
2ボールペン文具120
3付箋文具250
4デスクチェア家具24800
5書棚家具18500

解説

結論

NULL の置き換えは COALESCE(列, 代わりの値)。件数を 0 と出したいときは、外部結合+条件を ON 側+count(列) の 3 点セットです。

なぜ COALESCE か: NULL は「値が無い」ことを表す特別な状態で、値ではありません。そのため = NULL では判定できません(結果は真でも偽でもなく「不明」になります)。判定するなら IS NULL、置き換えるなら COALESCE を使います。

★条件を ON に書くか WHERE に書くか: これがこの問題の核心です。LEFT JOIN は「右側に相手がいなくても左側の行を残す」働きをしますが、WHERE は結合が終わったあとに働きます。相手がいない行は右側の列がすべて NULL になっているので、WHERE j.status = 'done' を通すと、そこで消えてしまいます。「左側の行を残したまま右側を絞りたい」なら、条件は ON 側に書きます。

★count(*) と count(列) の違い: count(*) は行を数えます。外部結合で相手がいなかった行も 1 行なので、1 と数えてしまいます。count(j.juchu_id) は NULL を数えないため、相手がいなかった行は 0 になります。「0 件を 0 と出す」ためには count(列) が必要です。

よくある間違い

①絞り込みの条件を WHERE に書いて外側の行を消す。②count(*) を使って 0 が 1 になる。③= NULL で判定しようとする。

根拠(一次情報)