Q1WHERE EXISTS (SELECT 1 FROM sales sale WHERE sale.emp_id = emp.emp_id) の説明として正しいものはどれですか。
EXISTS と相関サブクエリ
SQL の EXISTS と相関サブクエリを解説します。EXISTS / NOT EXISTS、NOT IN と NULL の落とし穴を EXISTS で安全に回避する書き方、IN との使い分けを社員・売上データで学べます。
本記事で使うデータ — employee / sales / department
EXISTS は「条件に合う行が 1 つでも存在するか だけ」を判定するサブクエリで、IN と似た使い方をします。
本記事では EXISTS / NOT EXISTS の基本、NOT IN と NULL の落とし穴を EXISTS で安全に回避する書き方、そして EXISTS と IN の読みやすさの使い分けを順に押さえます。
題材は社員データ 3 表です。
employee(社員 30 名)・sales(売上明細 50 件)・department(部署 6 件)を使い、「売上のある社員 / ない社員」「社員のいない部署」を抽出します。
EXISTS / NOT EXISTS — 行が存在するかだけを見る
WHERE EXISTS (SELECT ... ) は、サブクエリが 1 行でも返せば真、1 行も返さなければ偽になります。
サブクエリが何を SELECT するかは結果に影響しないため、慣習として SELECT 1 と書きます(値は使わず、行の有無だけを見るため)。
EXISTS の中で外側の表の列を参照する相関サブクエリにするのが基本形です。
「売上のある社員」は WHERE EXISTS (SELECT 1 FROM sales sale WHERE sale.emp_id = emp.emp_id)、「売上のない社員」はこれを否定した NOT EXISTS で取り出せます。
EXISTS は 1 行見つかった時点で判定を打ち切るため、存在チェックに向いた書き方です。
-- EXISTS: 売上のある社員
SELECT emp.emp_id, emp.name
FROM employee emp
WHERE EXISTS (
SELECT 1 FROM sales sale WHERE sale.emp_id = emp.emp_id
)
ORDER BY emp.emp_id;
NOT IN と NULL の落とし穴 — EXISTS は安全
「否定の絞り込み」を NOT IN で書くと、サブクエリ側に NULL が混ざったときに 結果が 0 行になる ことがあります。
x NOT IN (1, 2, NULL) は「x が 1 でなく、2 でなく、NULL でもない」と評価されますが、x <> NULL は真にならず常に NULL(不明)になるため、NOT IN 全体が真になりません。
詳しい理屈は サブクエリ ①(NOT IN と NULL の落とし穴) で解説しています。
employee.dept_id には NULL が混ざるので、「社員のいない部署」を WHERE dept_id NOT IN (SELECT dept_id FROM employee) で書くと、本来あるはずの Legal(社員が 1 人もいない部署)が消えて結果が 0 行になります。
NOT EXISTS は行の有無だけを見て NULL に影響されないため、この場面では NOT EXISTS が正しい結果を返します。
-- 落とし穴: NULL を含むサブクエリ + NOT IN は 0 行になる
SELECT dept_id, dept_name
FROM department
WHERE dept_id NOT IN (SELECT dept_id FROM employee);
-- → employee.dept_id に NULL があるため結果が 0 行
-- 安全: NOT EXISTS なら NULL の影響を受けない
SELECT d.dept_id, d.dept_name
FROM department d
WHERE NOT EXISTS (
SELECT 1 FROM employee emp WHERE emp.dept_id = d.dept_id
);
EXISTS は読みやすさで使い分ける
EXISTS は行の有無だけを見るため NULL があっても安全ですが、相関サブクエリを書くぶん IN より長く見えることがあります。
単純な存在判定では IN の方が読みやすい場面もあり、実務では文脈に応じて使い分けます。
一方、NOT IN のように NULL で結果が壊れる否定や、行の有無だけを確実に判定したいときは EXISTS / NOT EXISTS が安全です。
理解度チェック
まずは1問ずつ答えてみましょう。
Q2サブクエリ側に NULL が混ざりうるとき、否定の絞り込みを NOT IN で書くと起こりうる問題はどれですか。
Q3EXISTS を IN と使い分ける判断として、適切なものはどれですか。