SQLの学習で「EXISTS」が出てくると一気に難しく感じた私ですが、考え方はシンプルなようです。
一言でいえば 「そのサブクエリに結果が存在するかどうかを調べる」 ための仕組みです。
この記事で分かること(目次)
1. EXISTSとは?
EXISTS は「サブクエリに1件以上のデータが存在するか」を判定します。
SELECT 列名
FROM テーブルA
WHERE EXISTS (
SELECT *
FROM テーブルB
WHERE 条件
);
- サブクエリに1行でも結果があれば → TRUE
- 結果が0行なら → FALSE
例:部活に所属している学生を探す
SELECT 名前
FROM 学生 s
WHERE EXISTS (
SELECT *
FROM 部活 b
WHERE s.学生ID = b.学生ID
);
👉 「学生テーブル」の中から、部活テーブルに存在する学生だけを取り出します。
2. NOT EXISTSとは?
逆に、サブクエリの結果が1件も存在しないときにTRUE になります。
SELECT 名前
FROM 学生 s
WHERE NOT EXISTS (
SELECT *
FROM 部活 b
WHERE s.学生ID = b.学生ID
);
👉 部活に所属していない学生を探せます。
3. EXISTSとINの違い
似た使い方ができるのが IN句 です。
-- IN を使った例
SELECT 名前
FROM 学生
WHERE 学生ID IN (SELECT 学生ID FROM 部活);
ただし、大量データになると EXISTSの方が効率的 なケースが多いです。
→ EXISTSは「見つかった時点で検索終了」するのに対し、INはすべての値をリスト化する必要があるからです。
4. 練習問題
【問題1】
次のテーブルがあります。
学生(学生ID, 名前)
部活(学生ID, 部活名)
SQLを書いてください。
- 部活に所属している学生の名前を表示する
- 部活に所属していない学生の名前を表示する
解答1-1(所属している学生)
SELECT s.名前
FROM 学生 s
WHERE EXISTS (
SELECT *
FROM 部活 b
WHERE s.学生ID = b.学生ID
);
✅ 解説
EXISTSはサブクエリに結果があるかどうかを確認する。- 学生テーブルの1行ごとに、部活テーブルに同じ学生IDがあればTRUE → その学生が結果に出る。
解答1-2(所属していない学生)
SELECT s.名前
FROM 学生 s
WHERE NOT EXISTS (
SELECT *
FROM 部活 b
WHERE s.学生ID = b.学生ID
);
✅ 解説
NOT EXISTSはサブクエリの結果が0件のときにTRUEになる。- 部活テーブルに存在しない学生を取り出す。
【問題2】
注文(注文ID, 顧客ID, 日付)
顧客(顧客ID, 名前)
- 注文を一度もしたことがある顧客の名前を表示する
- 注文を一度もしたことがない顧客の名前を表示する
解答2-1(注文したことがある顧客)
SELECT c.名前
FROM 顧客 c
WHERE EXISTS (
SELECT *
FROM 注文 o
WHERE c.顧客ID = o.顧客ID
);
✅ 解説
- 顧客テーブルを基準に、注文テーブルに対応する行がある顧客だけを表示。
- 「一度でも注文があれば結果に出る」。
解答2-2(注文したことがない顧客)
SELECT c.名前
FROM 顧客 c
WHERE NOT EXISTS (
SELECT *
FROM 注文 o
WHERE c.顧客ID = o.顧客ID
);
✅ 解説
- 注文テーブルに存在しない顧客 → まだ注文したことがない人。
- 「新規顧客候補」などの分析に使える。
ちなみに・・・
この c.名前 の c. は、テーブルの別名(エイリアス) をつけて呼んでいるものです。
具体的に説明すると
SELECT c.名前
FROM 顧客 c
顧客というテーブルにcというあだ名(別名) をつけている- 以降は、
cを書けば「顧客テーブルのことですよ」とSQLがわかる
つまり、
c.名前= 顧客テーブルの「名前」列c.顧客ID= 顧客テーブルの「顧客ID」列
なぜ別名を使うの?
- 短く書ける
顧客.名前と毎回書くよりc.名前のほうがスッキリ。
- 複数のテーブルを結合するとき便利
SELECT c.名前, o.日付 FROM 顧客 c JOIN 注文 o ON c.顧客ID = o.顧客ID;→cは顧客、oは注文、と区別できるので混乱しない。 - 同じ列名が複数ある場合の衝突回避
- 例えば「顧客ID」が両方のテーブルにあるとき、どっちのIDかを指定できる。
📌まとめると:c. は 「顧客テーブルのことを、c って省略名で呼んでますよ」 という意味。
まとめ
- EXISTS:サブクエリに1件でもデータがあればTRUE
- NOT EXISTS:サブクエリに1件もデータがなければTRUE
- 実務でも「未注文の顧客」「未登録のユーザー」などを調べるのによく使う
🔍 過去問例:平成26年春期 午前 問28
問題内容(簡略化)
テーブル:
- 商品表(商品番号, 商品名, 単価等)
- 在庫表(在庫番号, 商品番号, 在庫数等)
以下と同じ結果が得られる SQL 文を選びなさい。
SELECT 商品番号
FROM 商品
WHERE 商品番号 NOT IN (SELECT 商品番号 FROM 在庫)
選択肢の中に、EXISTS や NOT EXISTS を使ったものがあり、同じ結果となるものを選ぶ問題です。 基本情報技術者試験ドットコム+1
正解の論理
この SQL 文の意味は:
- 「商品表 の中から、在庫表に 存在しない 商品番号 を表示せよ。」
すなわち、在庫表にその商品番号が 一度も出てこない商品 を選ぶ。
この “NOT IN サブ問合せ” を、 NOT EXISTS を使って書き換えると同じ意味になります。
EXISTSを使った書き換え例
SELECT 商品番号
FROM 商品 p
WHERE NOT EXISTS (
SELECT *
FROM 在庫 z
WHERE p.商品番号 = z.商品番号
);
pとzはテーブルの別名- サブクエリは「在庫テーブルに p.商品番号 が存在するかどうか」を調べる
NOT EXISTSを使って「存在しないもののみ」を取得
解答のポイント/注意点
NOT INはNULLが入る可能性のある場合に動きが複雑になることがあるが、この問題では在庫表の商品番号がNULLでないことが前提。EXISTS / NOT EXISTSは “相関副問合せ”(親クエリの行を使ってサブクエリを動かすもの)である。- 問題文をよく読み、「存在するかしないか」を問われているか/ “NOT” があるかに注意。
🔍 その他の出題例
ブログで見つかる他の SQL 過去問例から、「EXISTS / 副問合せ」が問われているものをまとめておきます:
- 選択肢で EXISTS を使っているもの(商品表と在庫表の関係など) KomuGeek+1
- 「IN vs EXISTS vs NOT IN vs NOT EXISTS」の意味や結果が同じかどうかを問うもの 基本情報技術者試験ドットコム+1
🧸 幼稚園児にもわかるたとえ
- 商品 = おもちゃ
- 在庫 = 遊ぶおもちゃが棚にあるかどうか
- 「棚にないおもちゃだけ持ってくる」 → NOT EXISTS のイメージ
✅ まとめ
| 項目 | キーワード |
|---|---|
| 問題の意図 | 存在するか/存在しないかを確認する |
| 主に使う句 | EXISTS / NOT EXISTS / IN / NOT IN |
| 書き換え可能性 | NOT IN ⇔ NOT EXISTS(NULL の有無など前提条件に注意) |
| 選択肢での判断ポイント | サブクエリの中でどのテーブル/どの列を参照しているか、NOT の有無、NULL の影響 |
