2026 年に受注が無い顧客
2026-01-01 以降に、取消されていない受注(status が 'done')が 1 件も無い顧客を取り出してください。列は「顧客名, 都道府県」の順、顧客番号(kokyaku_id)の小さい順に並べてください。受注が 1 件も無い顧客も対象に含みます。
この書き方が使えない製品があります そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server / Oracle Database
未確認: IBM Db2
- NOT IN でも同じことを書けますが、右側に NULL が 1 つでもあると 1 行も返らなくなります。NOT EXISTS にはこの落とし穴がありません。
- 標準 SQL の三値論理によるもので、実際に測った製品ではすべて同じ挙動でした。
この問題で使えるテーブル(名前をタップすると入力できます)
10 行
| 列 | 型 | NULL |
|---|---|---|
| 🔑 | int | 不可 |
| int | 不可 | |
| date | 不可 | |
| text | 不可 |
データを見る(先頭 5 行)
| juchu_id | kokyaku_id | juchu_on | status |
|---|---|---|---|
| 1001 | 1 | 2025-11-05 | done |
| 1002 | 2 | 2025-11-18 | done |
| 1003 | 1 | 2025-12-02 | done |
| 1004 | 3 | 2025-12-09 | cancel |
| 1005 | 4 | 2025-12-24 | done |
17 行
| 列 | 型 | NULL |
|---|---|---|
| 🔑 | int | 不可 |
| 🔑 | int | 不可 |
| int | 不可 | |
| int | 不可 | |
| numeric(10,0) | 不可 |
データを見る(先頭 5 行)
| juchu_id | gyo_no | shohin_id | suryo | tanka |
|---|---|---|---|---|
| 1001 | 1 | 1 | 20 | 180 |
| 1001 | 2 | 2 | 30 | 120 |
| 1002 | 1 | 4 | 2 | 23800 |
| 1002 | 2 | 5 | 1 | 18500 |
| 1003 | 1 | 6 | 4 | 4200 |
5 行
| 列 | 型 | NULL |
|---|---|---|
| 🔑 | int | 不可 |
| text | 不可 | |
| text | 可 | |
| date | 不可 |
データを見る(先頭 5 行)
| kokyaku_id | kokyaku_name | pref | created_on |
|---|---|---|---|
| 1 | 青葉工業 | 東京都 | 2024-05-10 |
| 2 | 白樺物産 | 大阪府 | 2024-08-01 |
| 3 | 黒松システム | 東京都 | 2025-01-15 |
| 4 | 赤坂商会 | NULL | 2025-03-20 |
| 5 | 三田商事 | 愛知県 | 2025-06-01 |
7 行
| 列 | 型 | NULL |
|---|---|---|
| 🔑 | int | 不可 |
| text | 不可 | |
| text | 不可 | |
| numeric(10,0) | 不可 |
データを見る(先頭 5 行)
| shohin_id | shohin_name | category | price |
|---|---|---|---|
| 1 | ノート | 文具 | 180 |
| 2 | ボールペン | 文具 | 120 |
| 3 | 付箋 | 文具 | 250 |
| 4 | デスクチェア | 家具 | 24800 |
| 5 | 書棚 | 家具 | 18500 |
解説
結論
「〜が 1 件も無い」は NOT EXISTS で書きます。括弧の中で、外側の行と結びつける条件を書くのが要点です。
なぜ
NOT EXISTS は「括弧の中が 1 行も返さないこと」を各行について判定します。行の中身は見ないので、SELECT の後ろは 1 でも * でも構いません。
★「無いもの」を探すときに一番やりがちな間違いは、条件をひっくり返して「別のものがあるもの」を探してしまうことです。「2026 年に受注が無い顧客」と「2025 年に受注がある顧客」は違います。前者には、そもそも受注が 1 件も無い顧客が含まれますが、後者には含まれません。このデータには受注が 1 件も無い顧客がいるので、その違いが結果に現れます。
⚠️ NOT IN との違い: NOT IN (SELECT ...) でも同じことを書けますが、副問い合わせの結果に NULL が 1 つでも混ざると、結果は「該当なし」になります。SQL の三値論理では「NULL と等しくない」が真にならないためです。NOT EXISTS ならこの罠はありません。迷ったら NOT EXISTS を選んでください。
よくある間違い
①括弧の中に外側との結びつけ条件を書き忘れ、どの顧客でも同じ判定になってしまう。②NOT を付け忘れる。③条件の一部(取消・期間)を括弧の外に書いてしまう。
根拠(一次情報)
- PostgreSQL 18 マニュアル: 副問い合わせ式(EXISTS / IN / NOT IN)一次情報・確認 2026-07-28
- PostgreSQL 18 マニュアル: 比較関数と演算子(NULL の扱い)一次情報・確認 2026-07-28