IPA|情報処理技術者試験

SQLのWHERE句マスター講座│INとEXISTSの違いからNULL・LIKE・ALLまで網羅【データベース試験対策】

データベーススペシャリスト試験や応用情報技術者試験の午後問題で、必ずと言っていいほど登場するのがSQLのWHERE句です。単純な条件指定だけでなく、NULLの扱いやサブクエリ(副問い合わせ)と連携した複雑な検索条件を正しく読み解き、あるいは作成する能力が問われます。特に、LIKEによるパターンマッチング、INEXISTSによる存在チェック、そしてSOMEALLを使った数量比較は、つまずきやすいポイントの代表格と言えるでしょう。本記事では、これらのWHERE句で使われる主要な検索条件について、それぞれの役割と正しい使い方を網羅的に解説します。具体的なSQL例と実行結果、そして各演算子の使い分けの勘所を学び、得点力アップに繋げましょう。


NULL値の判定 | =ではなくIS NULLを使う理由

WHERE句を学ぶ上で、最初の関門となるのがNULLの扱いです。NULLは「値が存在しない」ことを示す特殊な状態であり、0や空文字列('')とは全く異なります。そのため、カラム名 = NULLのような比較演算子を用いた判定は意図した結果を返しません。NULLかどうかを判定するには、専門の述語である IS NULL または IS NOT NULL を使用する必要があります。

なぜ=ではダメなのか?

SQLの世界では、NULLと他の値(NULL自身を含む)を比較した結果は、TRUEでもFALSEでもなく、「不明(UNKNOWN」として扱われます。WHERE句は条件がTRUEになる行だけを抽出するため、評価結果がUNKNOWNになる行は結果セットに含まれません。

例えば、「bonus(ボーナス額)が登録されていない社員」を抽出したいと考えます。

【テーブル例:employees】

id name bonus
1 佐藤 100000
2 鈴木 NULL
3 高橋 0

このテーブルに対して、間違ったSQLと正しいSQLを実行してみましょう。

【間違いSQL】bonus = NULL


SELECT * FROM employees WHERE bonus = NULL;

【実行結果】

(0件)

bonusNULLである鈴木さんのレコードが抽出されません。NULL = NULLの評価がUNKNOWNになるためです。

【正しいSQL】IS NULL


SELECT * FROM employees WHERE bonus IS NULL;

【実行結果】

id name bonus
2 鈴木 NULL

このように、IS NULLを使うことでNULL値を持つ行を正しく抽出できます。逆に、NULLでない行を抽出する場合はIS NOT NULLを使用します。データベーススペシャリスト試験などでは、このNULLの特性を突いた問題が頻出するため、「= NULLは使わない」と機械的に覚えてしまいましょう。


LIKE演算子によるあいまい検索│ %_の使い分け

WHERE句で文字列の一部が一致するレコードを検索したい場合、LIKE演算子を使用します。完全一致を調べる=とは異なり、ワイルドカードと呼ばれる特殊な記号を使って「あいまい検索(部分一致検索)」を実現できるのが特徴です。LIKE演算子で使われる主なワイルドカードは%_の2つです。

  • %(パーセント): 0文字以上の任意の文字列を表します。
  • _(アンダースコア): 任意の一文字を表します。

これらのワイルドカードを組み合わせることで、様々なパターンの文字列検索が可能になります。

【テーブル例:products】

product_id product_name
A-001 応援タオル
A-002 復刻版タオル
B-001 スポーツドリンク
B-002 スポーツウェア

具体的な使用例

1. 前方一致:「応援」から始まる商品


SELECT * FROM products WHERE product_name LIKE '応援%';

【実行結果】

product_id product_name
A-001 応援タオル

2. 後方一致:「タオル」で終わる商品


SELECT * FROM products WHERE product_name LIKE '%タオル';

【実行結果】

product_id product_name
A-001 応援タオル
A-002 復刻版タオル

3. 中間一致:「スポーツ」を含む商品


SELECT * FROM products WHERE product_name LIKE '%スポーツ%';

【実行結果】

product_id product_name
B-001 スポーツドリンク
B-002 スポーツウェア

4. _を使った文字数指定

LIKE 'スポーツ__' は「スポーツ」+ 2文字の計7文字の文字列にマッチします。


SELECT * FROM products WHERE product_name LIKE 'スポーツ__';

【実行結果】

(0件)
-- 「スポーツドリンク」「スポーツウェア」は文字数が合わないためヒットしません。もし product_name に「スポーツ茶」というデータがあれば、LIKE 'スポーツ_' でヒットします。

%_自体を検索したい場合

%_という文字そのものを検索したい場合は、ESCAPE句を使ってエスケープ文字を定義します。例えば、\をエスケープ文字に指定すると、\%%という文字、\__という文字を検索できます。


-- '割引率:10%'という文字列を検索する例
SELECT * FROM campaigns WHERE campaign_name LIKE '%10\%%' ESCAPE '\';

BETWEENINによる範囲検査│午後試験での頻出パターン

数値や日付、あるいは複数の値を対象とした範囲を指定する際には、BETWEEN演算子IN演算子が非常に役立ちます。これらは>=<=ORを複数組み合わせるよりも、SQLを簡潔かつ直感的に記述できるため、午後試験の長文SQLを読解する上で必須の知識です。

BETWEEN:連続的な範囲の指定

BETWEENは、指定した2つの値の間(両端の値を含む)にあるデータを抽出します。数値や日付などの連続したデータの範囲指定に用いられます。

カラム名 BETWEEN 値1 AND 値2カラム名 >= 値1 AND カラム名 <= 値2 と等価です。

【テーブル例:test_scores】

student_id score
S001 85
S002 60
S003 92
S004 75

使用例:点数が75点から90点の間の生徒を抽出


SELECT * FROM test_scores WHERE score BETWEEN 75 AND 90;

【実行結果】

student_id score
S001 85
S004 75

BETWEEN境界値を含む(以上・以下)という点をしっかり覚えておきましょう。

IN:離散的な値のリスト指定

INは、括弧 () で囲まれたリストの中に含まれる値と一致するデータを抽出します。ORを何度も書く必要がなくなり、コードの可読性が大幅に向上します。

カラム名 IN (値1, 値2, ...)カラム名 = 値1 OR カラム名 = 値2 OR ... と等価です。

【テーブル例:employees】

id name department_id
1 佐藤 D01
2 鈴木 D03
3 高橋 D02
4 田中 D01

使用例:部署IDがD01(人事)またはD03(営業)の社員を抽出


SELECT * FROM employees WHERE department_id IN ('D01', 'D03');

【実行結果】

id name department_id
1 佐藤 D01
2 鈴木 D03
4 田中 D01

INのリストには、直接値を記述するだけでなく、サブクエリ(副問い合わせ)を指定することも可能です。これは非常に強力で、応用情報やDBスペシャリスト試験では頻出のパターンです。

サブクエリ使用例:東京支社に所属する社員を抽出

departmentsテーブルからlocationが'東京'である部署IDのリストを取得し、そのリストに所属する社員をemployeesテーブルから検索します。


SELECT * FROM employees
WHERE department_id IN (SELECT department_id FROM departments WHERE location = '東京');

JOINの結合条件をWHERE句に書く際の注意点│内部結合と外部結合

JOINは複数のテーブルを特定のカラム(キー)を使って結合するための句です。最近のSQLでは、結合条件をFROM句内のONで指定するのが一般的ですが、古い記述法や一部のデータベースではWHERE句に結合条件を記述することもあります。この違いと、特に外部結合(OUTER JOIN)での注意点を理解しておくことは、レガシーシステムのSQL読解などで役立ちます。

ANSI SQL-92形式(ON句を使用) vs SQL-89形式(WHERE句を使用)

employees(社員)テーブルとdepartments(部署)テーブルをdepartment_idで結合する場合を考えます。

【推奨されるSQL-92形式】


SELECT e.name, d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id;

この形式では、JOINで結合するテーブルを明示し、ONで結合条件、WHEREで絞り込み条件と、役割が明確に分かれています。

【古いSQL-89形式】


SELECT e.name, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id;

FROM句でテーブルをカンマ区切りで列挙し、WHERE句に結合条件を記述します。両者に紐づくレコードのみが抽出されるため、結果として内部結合(INNER JOIN)と同じになります。

WHERE句での外部結合と特有の記号 (+)

問題は外部結合です。LEFT JOINRIGHT JOINWHERE句で表現する場合、Oracleなど一部のデータベースでは(+)という独自の演算子を使います。

LEFT JOINの例:部署に所属していない社員も含めて一覧表示

【SQL-92形式のLEFT JOIN`】


SELECT e.name, d.department_name
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id;

社員テーブルを主軸(左側)とし、部署名が存在しない社員(例えばdepartment_idNULLの社員)も結果に含めます。

【Oracleの(+)を使ったWHERE`句での表現】


SELECT e.name, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id (+);

(+)は、情報が不足している側(この場合はdepartmentsテーブル側)の結合カラムに付けます。「e.department_idに対応するd.department_idが無くても、eの行は表示してね」という意味合いになります。

この(+)記号は、どちらのテーブルが主軸なのかを瞬時に判断する必要があり、読解が難しいです。情報処理技術者試験でこの形式が出題されることは稀ですが、実務で遭遇する可能性はゼロではありません。原則としてON句を使うべきですが、知識として知っておくと良いでしょう。重要なのは、WHERE句に書かれた=`が、事実上の内部結合として機能している場合がある、という点です。

EXISTSによる存在チェック│INとの違いと相関サブクエリ

EXISTSは、サブクエリ(副問い合わせ)が1件でも結果を返せばTRUE、1件も返さなければFALSEを返す演算子です。特定の条件を満たすデータが「存在するかどうか」だけを判定したい場合に使用します。INがサブクエリの結果リストと「値」を比較するのに対し、EXISTSは結果の「有無」だけを見る、という点が根本的な違いです。

EXISTSは通常、相関サブクエリと組み合わせて使われます。相関サブクエリとは、外側のクエリ(主クエリ)のカラムを内側のクエリ(サブクエリ)のWHERE句で参照するような、相互に関連したサブクエリのことです。

EXISTSの動作イメージ

  1. 主クエリの行が1行ずつ処理される。
  2. その行の値を使い、サブクエリが実行される。
  3. サブクエリが1件でも結果を返せば、その主クエリの行はTRUEと判定され、結果セットに含まれる。
  4. 主クエリの全行に対して、1〜3を繰り返す。

使用例:一度でも商品を購入したことがある顧客を一覧表示する

customers(顧客)テーブルとorders(注文)テーブルを使います。

【テーブル例:customers】

customer_id name
C01 斎藤
C02 中村
C03 吉田

【テーブル例:orders】

order_id customer_id order_date
1 C01 2025-08-01
2 C03 2025-08-02
3 C01 2025-08-05

SELECT c.customer_id, c.name
FROM customers c
WHERE EXISTS (
  SELECT *
  FROM orders o
  WHERE o.customer_id = c.customer_id -- 主クエリのc.customer_idを参照(相関サブクエリ)
);

【実行結果】

customer_id name
C01 斎藤
C03 吉田

このSQLは、customersテーブルの各行(斎藤さん、中村さん、吉田さん)について、ordersテーブル内に対応するcustomer_idを持つ注文記録が存在するかを調べています。中村さん(C02)は注文記録がないため、サブクエリが0件となり、EXISTSFALSEを返すので結果から除外されます。

IN vs EXISTS の使い分け

観点 IN EXISTS
比較対象 のリスト 結果セットの有無
得意な処理 サブクエリが返す結果セットが小さい場合 サブクエリが返す結果セットが大きい場合
サブクエリ 非相関サブクエリで使われることが多い 相関サブクエリで使われることが多い
NULLの扱い サブクエリ結果にNULLが含まれると意図しない結果になることがある(特にNOT IN NULLの影響を受けにくい

一般的に、EXISTSの方が高速に動作するケースが多いとされています。INはサブクエリを一度だけ実行し、その結果リストをメモリに保持して主クエリと比較しますが、EXISTSはサブクエリが1件でも見つかった時点で評価を打ち切るためです。DBスペシャリスト試験では、このパフォーマンスの違いを意識した選択が求められることがあります。


SOMEALLによる数量比較│ANYとの関係とNOTの挙動

SOMEALLは、INEXISTSと同様にサブクエリと組み合わせて使う比較演算子です。サブクエリが返す複数の結果値と、主クエリの値を比較します。

  • SOME: サブクエリが返す結果のいずれか1つでも条件を満たせばTRUEになります。
  • ALL: サブクエリが返すすべての結果に対して条件を満たせばTRUEになります。

なお、ANYSOME`と全く同じ意味を持つシノニム(同義語)です。SQLの標準規格ではSOMEが採用されていますが、ANYも広く使われています。

【テーブル例:products】

name category price
A 文房具 100
B 文房具 150
C 食品 200
D 食品 300

SOME (ANY) の使用例

「文房具カテゴリのいずれかの商品よりも価格が高い商品」を抽出します。
サブクエリ (SELECT price FROM products WHERE category = '文房具')(100, 150) という結果を返します。


SELECT *
FROM products
WHERE price > SOME (SELECT price FROM products WHERE category = '文房具');
-- WHERE price > ANY (...) と同じ

この条件は price > 100 OR price > 150 と展開されます。price > 100 を満たせば良いため、100より大きいすべての商品が対象です。

【実行結果】

name category price
B 文房具 150
C 食品 200
D 食品 300

ALLの使用例

「文房具カテゴリのすべての商品よりも価格が高い商品」を抽出します。


SELECT *
FROM products
WHERE price > ALL (SELECT price FROM products WHERE category = '文房具');

この条件は price > 100 AND price > 150 と展開されます。両方を満たす必要があるため、price > 150 が条件となります。

【実行結果】

name category price
C 食品 200
D 食品 300

IN, =, <> との関係

これらの演算子は、他の演算子と密接な関係にあります。

  • = SOME (リスト)IN (リスト)` と全く同じです。「リストのいずれかと等しい」という意味になります。
  • <> ALL (リスト)NOT IN (リスト)` とほぼ同じです。「リストのすべてと等しくない」という意味です。(ただし、NOT INはリスト内にNULLがあると結果が0件になるという罠がありますが、<> ALLNULLを無視する挙動を示すDBMSもあり、厳密には挙動が異なる場合があります。)
  • <> SOME (リスト)は「リストのいずれかと等しくない」という意味です。例えばリストが (100, 150) の場合、100でないか、または150でない、という条件なので、ほとんどのデータがTRUEになり、実用的な使い方は稀です。

情報処理技術者試験では、> ALL(最大値より大きい)、< ALL(最小値より小さい)、> SOME(最小値より大きい)、< SOME(最大値より小さい)といった使い分けが問われることがあります。それぞれの演算子がどのような意味になるか、具体例を元に整理しておきましょう。

-IPA|情報処理技術者試験