資格道場 › レッスン一覧 › データベース
データベース・6/13・15分

SQLの検索条件(WHERE・LIKE・IN・EXISTS)

ゴール

WHERE句の AND・OR・NOT、LIKE、IN、BETWEEN、EXISTS を正しく読み書きし、「同じ結果になる SQL はどれか」「実行結果はどれか」という過去問を自力で解けるようになる。

SQL の検索条件は、データベース分野で毎回のように出題されます。実務でも「この条件で抽出してください」という要件を SQL に落とすときにそのまま使う考え方で、AND と OR の取り違えは抽出漏れや余計なデータの混入につながります。

このレッスンで稽古する(用語チェック・過去問)

結論:WHERE句は「行を残すかどうかのふるい」

WHERE句は、表の1行ずつに条件を当てはめ、真(条件を満たす)になった行だけを残す部分です。条件は AND・OR・NOT でつなげられ、LIKE(文字のパターン)、IN(候補の一覧)、EXISTS(別の表に該当行があるか)などの部品を組み合わせます。

試験で問われるのは、次の2パターンにほぼ集約されます。

  • 書き換え:「この SQL と同じ結果になるのはどれか」(IN ⇔ OR、NOT IN ⇔ NOT EXISTS)
  • 実行:「この SQL の結果はどれか」(表に条件を当てはめて、残る行を数える)

どちらも、1行ずつ条件に代入して真か偽かを確かめるのが確実な解き方です。

表の各行行1行2行3行4WHERE 条件1行ずつ判定真偽真の行だけ残る行1・行3偽の行は捨てる行2・行4
WHERE句は表の行を1行ずつ条件に当てはめ、真になった行だけを残し、偽の行は捨てる。

AND・OR・NOT と優先順位

条件は AND(かつ)=両方が真のときだけ真、OR(または)=どちらかが真なら真、NOT(でない)=真と偽を反転の3つで組み立てます。

演算子 意味 残る行 優先順位
NOT 否定 条件を満たさない行 1(最初に計算)
AND かつ 両方を満たす行(絞り込む) 2
OR または どちらかを満たす行(広げる) 3(最後に計算)

AND は OR より先に計算されます(掛け算が足し算より先なのと同じです)。X OR Y AND Z は X OR (Y AND Z) と解釈されるため、括弧が無い選択肢は意図どおりに動かないことが多いです。

「どの期でも 3,000 万円以上」のように全部を満たす条件は AND、「どれか1つでも」なら OR です。問題文の「どの〜も」「すべて」を見たら AND と考えましょう。

X OR Y AND Z の読まれ方② 最後に ORX① 先に ANDYZ= X OR (Y AND Z)
括弧の無い X OR Y AND Z は、AND が先にまとまり X OR (Y AND Z) と読まれる。

平均の条件は「合計」に直して比べる

過去問では「4 期の平均が 4,000 万円以上」を 合計 ≥ 4,000 万円 × 4 と書き換えた選択肢が正解になりました。平均 ≥ 基準 は、両辺に期数を掛けた 合計 ≥ 基準 × 期数 と同じ意味です。

ひっかけは2つあります。単位(表は千円単位なので、4,000 万円=40,000 千円)と、合計を平均の基準のまま比べるミス(合計 ≥ 40,000 では条件がゆるすぎる)です。

2つの表をまたぐときは「結合条件 AND 絞り込み条件」

FROM BUSHO, SHAIN のように2つの表を並べると、まず直積(全行同士の組合せ。2行×8行=16行)が作られます。そこから正しい組合せだけを残すのが結合条件(例:BU_CODE = S_SHOZOKU)で、これを書き忘れると、関係の無い部署名がくっついた行まで残ります。

つまり WHERE には「結合条件 AND 絞り込みたい条件」の両方が必要です。前のレッスンで学んだ結合を、WHERE で書く形がこれです。

FROM BUSHO, SHAIN の直積SHAIN(8行)部署1部署2○○×○××○×××○×○○×○2行 × 8行 = 16行(直積)結合条件BU_CODE = S_SHOZOKU○ だけ残る(× は無関係な組合せ)AND 絞り込みたい条件必要な行だけが残る
2つの表を並べるとまず全組合せの直積ができ、結合条件で正しい組合せだけに絞り、さらに AND で絞り込む。

排他的論理和:「どちらか一方だけ」の書き方

排他的論理和(XOR)は「A と B のどちらか一方だけが真」という条件です。SQL に XOR はないので、AND・OR・NOT で組み立てます。

(A OR B) AND NOT (A AND B) =「少なくとも一方は真」かつ「両方真ではない」

A(国語が平均以上) B(数学が平均以上) A OR B NOT (A AND B) 結果
真 真 真 偽 偽
真 偽 真 真 真
偽 真 真 真 真
偽 偽 偽 真 偽

ほかの選択肢の (A AND B) AND NOT (A AND B) などは、どんな行でも偽(矛盾した条件)になり、1行も残りません。「X AND NOT X」の形を見たら、すぐに候補から外して構いません。

(A OR B) AND NOT (A AND B)A だけ→ 真B だけ→ 真両方→ 偽A:国語が平均以上B:数学が平均以上緑だけ残る(重なりと外側は偽)
排他的論理和は「A だけ」と「B だけ」の部分が真で、両方が真の重なりと、どちらも偽の外側は偽になる。

LIKE:文字のパターンで探す

LIKE は文字列を「型」で探す述語(真偽を返す条件の部品)です。%=0文字以上の任意の文字列、_(アンダースコア)=ちょうど1文字を表します。% は、トランプのジョーカーのように「何文字でも当てはまる空欄」と考えると分かりやすいです。

書き方 意味 'UNIX入門' '入門UNIX' 'やさしいUNIX講座'
LIKE 'UNIX' 完全一致 × × ×
LIKE 'UNIX%' 前方一致(UNIX で始まる) ○ × ×
LIKE '%UNIX' 後方一致(UNIX で終わる) × ○ ×
LIKE '%UNIX%' 部分一致(どこかに含む) ○ ○ ○

「含む」と書いてあれば '%UNIX%' です。また、LIKE は文字そのものを比べるので、ひらがなの「めん」とカタカナの「メン」は別の文字として扱われ、一致しません。

IN と BETWEEN:候補の一覧と範囲

IN は「この候補のどれかに等しい」という条件で、= を OR でつないだものと同じ結果になります。

WHERE 仕入先ID IN ('M002', 'M004')
-- ↓ 同じ結果
WHERE 仕入先ID = 'M002' OR 仕入先ID = 'M004'
書き方 意味 M002〜M004 に対する結果
IN ('M002','M004') M002 または M004 M002・M004
= 'M002' OR = 'M004' IN と同じ M002・M004
= 'M002' AND = 'M004' 1つの列が同時に2つの値(ありえない) 0行
BETWEEN 'M002' AND 'M004' M002 以上 M004 以下(両端を含む範囲) M002・M003・M004
INTERSECT(共通部分) 両方の結果に共通する行 0行

IN は副問合せ(SQL の中に入れた別の SELECT 文)と組み合わせて、部品ID IN (SELECT 部品ID FROM 在庫 WHERE …) のようにも使います。CASE 式(条件によって値を出し分ける式)の中で使っても、行を絞り込むのではなく、表示する値(○ か ×)を切り替えるだけです。

EXISTS と NOT EXISTS:相関副問合せ

EXISTS (副問合せ) は、副問合せが1行でも返せば真、0行なら偽になります。NOT EXISTS はその逆です。

ここで鍵になるのが相関副問合せです。これは、副問合せの中で外側の表の列(例:商品.商品番号)を参照し、外側の1行ごとに副問合せをやり直す書き方です。出席簿の1人ずつについて「在庫帳にこの番号はある?」と確かめる係を思い浮かべてください。

flowchart TD
  A["商品表から1行取り出す"] --> B["在庫表で 商品.商品番号 = 在庫.商品番号 の行を探す"]
  B --> C{"1行でも見つかった?"}
  C -->|"見つかった"| D["EXISTS は真 / NOT EXISTS は偽"]
  C -->|"0行"| E["EXISTS は偽 / NOT EXISTS は真"]
  D --> F["次の商品の行へ"]
  E --> F

このため、次の2つは同じ結果(在庫表に無い商品の番号)になります。

SELECT 商品番号 FROM 商品
 WHERE 商品番号 NOT IN (SELECT 商品番号 FROM 在庫)

SELECT 商品番号 FROM 商品
 WHERE NOT EXISTS (SELECT 商品番号 FROM 在庫
                    WHERE 商品.商品番号 = 在庫.商品番号)
書き方 副問合せの性質 結果
NOT IN (SELECT …) 外と無関係に1回だけ実行 一覧に無い行
NOT EXISTS (… WHERE 商品.番号 = 在庫.番号) 相関:1行ごとに実行 対応する行が無い行(NOT IN と同じ)
EXISTS (… 相関条件あり) 相関 対応する行がある行(逆の結果)
EXISTS (SELECT … FROM 商品) 相関条件なし 全行が真か、全行が偽(絞り込めない)

※ 試験では NOT IN と NOT EXISTS を等価として扱います(副問合せの結果に NULL が含まれると、厳密には結果が異なります)。

例題 1

平均4,000万円以上・各期3,000万円以上を SQL にする

次の表は,営業担当者のある年度の販売実績である。この表の第 1 期から第 4 期の販売金額の平均が 4,000 万円以上で,どの期でも 3,000 万円以上販売している営業担当者の名前を求める SQL 文として,適切なものはどれか。ここで,金額の単位は千円とする。
販売実績(金額の単位は千円)
番号名前第 1 期第 2 期第 3 期第 4 期
123山田 一郎29,60031,90036,60041,500
594鈴木 太郎43,50045,30030,40046,400
612佐藤 花子49,60039,40042,30051,100
⋮⋮⋮⋮⋮⋮

ア SELECT 名前 FROM 販売実績 WHERE (第 1 期 + 第 2 期 + 第 3 期 + 第 4 期) / 4 >= 40000 OR 第 1 期 >= 30000 OR 第 2 期 >= 30000 OR 第 3 期 >= 30000 OR 第 4 期 >= 30000
イ SELECT 名前 FROM 販売実績 WHERE (第 1 期 + 第 2 期 + 第 3 期 + 第 4 期) >= 40000 AND 第 1 期 >= 30000 AND 第 2 期 >= 30000 AND 第 3 期 >= 30000 AND 第 4 期 >= 30000
ウ SELECT 名前 FROM 販売実績 WHERE 第 1 期 > 40000 OR 第 2 期 > 40000 OR 第 3 期 > 40000 OR 第 4 期 > 40000 AND 第 1 期 >= 30000 OR 第 2 期 >= 30000 OR 第 3 期 >= 30000 OR 第 4 期 >= 30000
エ SELECT 名前 FROM 販売実績 WHERE (第 1 期 + 第 2 期 + 第 3 期 + 第 4 期) >= 160000 AND 第 1 期 >= 30000 AND 第 2 期 >= 30000 AND 第 3 期 >= 30000 AND 第 4 期 >= 30000

出典:平成23年度 特別試験 基本情報技術者試験 午前 問30

解き方と答えを見る
  1. 単位をそろえる:表は千円単位なので、4,000万円=40,000千円、3,000万円=30,000千円。
  2. 平均の条件を合計に直す:(第1期+第2期+第3期+第4期) ÷ 4 ≥ 40,000 → 両辺に4を掛けて、合計 ≥ 160,000。
  3. 「どの期でも3,000万円以上」は4つすべてを満たすので AND:第1期 ≥ 30000 AND 第2期 ≥ 30000 AND 第3期 ≥ 30000 AND 第4期 ≥ 30000。
  4. 2つの条件も両方必要なので AND で結ぶ → エ。
  5. 検算(山田さん):合計=29,600+31,900+36,600+41,500=139,600 < 160,000、第1期も29,600 < 30,000 なので残らない。佐藤さんは合計182,400 ≥ 160,000 で、各期とも30,000以上なので残る。
  6. 他の選択肢を消す:アは OR で条件がゆるすぎる。イは合計を40,000と比べている(平均の基準のまま)。ウは OR と AND が混在していて、AND が先に計算されるため意図と違う条件になる。

答え:エ(合計 ≥ 160000 AND 各期 ≥ 30000 を4つとも AND)

例題 2

LIKE '%めん' AND 単価 < 330 の実行結果

“商品”表に対して,次の SQL 文によって得られる結果はどれか。 SELECT 商品番号 FROM 商品 WHERE 商品名 LIKE '%めん' AND 単価 < 330
商品表:
商品番号商品名単価
100ラーメン305
130きしめん285
205チャーシューメン700
267おかめうどん300
307そうめん350
390カレーライス400
401チャーハン320
420きつねうどん298

ア [表] 商品番号: 100, 130
イ [表] 商品番号: 100, 130, 267, 420
ウ [表] 商品番号: 130
エ [表] 商品番号: 130, 307

出典:基本情報技術者試験 科目A免除 修了試験 201007 実施分 問33

解き方と答えを見る
  1. 条件①:LIKE '%めん' = 末尾がひらがなの『めん』。
  2. 1行ずつ確認:ラーメン(カタカナ『メン』→×)、きしめん(○)、チャーシューメン(カタカナ→×)、おかめうどん(『うどん』で終わる→×)、そうめん(○)、それ以外も×。
  3. 条件①で残るのは、きしめん(130・285円)とそうめん(307・350円)。
  4. 条件②:単価 < 330。きしめん 285 < 330 →○、そうめん 350 < 330 →×。
  5. AND なので両方を満たす行だけが残る → 商品番号130のみ。

答え:ウ(130 のみ)

例題 3

「1教科だけ平均以上」を AND/OR/NOT で表す

国語と数学の試験を実施し,2 教科の成績は氏名とともに“得点”表に記録されている。1 教科は平均点以上で,残りの 1 教科は平均点未満の生徒氏名を“得点”表から抽出する SQL 文はどれか。ここで,条件文 A と条件文 B には,それぞれ次の条件が与えられているものとする。 〔条件文〕 A 国語の点数が国語の平均点以上 B 数学の点数が数学の平均点以上

ア SELECT 生徒氏名 FROM 得点 WHERE (A AND B) AND NOT (A AND B)
イ SELECT 生徒氏名 FROM 得点 WHERE (A AND B) AND NOT (A OR B)
ウ SELECT 生徒氏名 FROM 得点 WHERE (A OR B) AND NOT (A AND B)
エ SELECT 生徒氏名 FROM 得点 WHERE (A OR B) AND NOT (A OR B)

出典:基本情報技術者試験 科目A免除 修了試験 20250608 実施分 問20

解き方と答えを見る
  1. 求めたいのは「A と B のどちらか一方だけが真」=排他的論理和。
  2. 「少なくとも一方が真」は A OR B。
  3. 「両方が真ではない」は NOT (A AND B)。
  4. 2つを同時に満たす必要があるので AND で結ぶ:(A OR B) AND NOT (A AND B) → ウ。
  5. ア・エは『X AND NOT X』の形で常に偽。イは A AND B が真(両方真)のとき NOT (A OR B) が必ず偽になるので、これも常に偽。

答え:ウ

例題 4

CASE 式の中の IN 副問合せの実行結果

“部品”表と“在庫”表に対して SQL 文を実行した結果はどれか。ここで,実線の下線は主キーを表す。
部品(主キー: 部品ID)
部品ID部品名
01メモリ
02ディスプレイ
03ディスク
04マウス
05キーボード
在庫(主キー: 場所, 部品ID)
場所部品ID在庫数
東京0110
東京0320
東京0420
大阪0225
大阪0430
〔SQL 文〕 SELECT 部品名, CASE WHEN 部品ID IN (SELECT 部品ID FROM 在庫 WHERE 場所 = '東京' AND 在庫数 > 10 ) THEN '○' ELSE '×' END AS 東京, CASE WHEN 部品ID IN (SELECT 部品ID FROM 在庫 WHERE 場所 = '大阪' AND 在庫数 > 10 ) THEN '○' ELSE '×' END AS 大阪 FROM 部品

ア [図] 表(部品名/東京/大阪): ディスプレイ ×/○,ディスク ○/×,マウス ○/○
イ [図] 表(部品名/東京/大阪): メモリ ×/×,ディスプレイ ×/○,ディスク ○/×,マウス ○/○
ウ [図] 表(部品名/東京/大阪): メモリ ×/×,ディスプレイ ×/○,ディスク ○/×,マウス ○/○,キーボード ×/×
エ [図] 表(部品名/東京/大阪): メモリ ×/×,ディスプレイ ×/○,ディスク ×/×,マウス ○/○,キーボード ×/×

出典:基本情報技術者試験 科目A免除 修了試験 20260726 実施分 問20

解き方と答えを見る
  1. 東京の副問合せ:場所='東京' AND 在庫数 > 10 → 03(20)と04(20)。01は在庫数10で『> 10』を満たさない。結果は {03, 04}。
  2. 大阪の副問合せ:場所='大阪' AND 在庫数 > 10 → 02(25)と04(30)。結果は {02, 04}。
  3. 外側は FROM 部品 で WHERE が無いので、部品の5行がすべて結果に出る(CASE は値を切り替えるだけで、行を減らさない)。
  4. 各部品を判定:メモリ01(東京×・大阪×)、ディスプレイ02(×・○)、ディスク03(○・×)、マウス04(○・○)、キーボード05(×・×)。
  5. 5行で、この並びになっている選択肢 → ウ。ア・イは行数が足りない。エはディスクの東京が×になっている。

答え:ウ

例題 5

NOT IN を NOT EXISTS に書き換える

“商品”表,“在庫”表に対する次の SQL 文の結果と同じ結果が得られる SQL 文はどれか。ここで,下線部は主キーを表す。
SELECT 商品番号 FROM 商品 WHERE 商品番号 NOT IN (SELECT 商品番号 FROM 在庫) 商品(主キー: 商品番号): | 商品番号 | 商品名 | 単価 | 在庫(主キー: 倉庫番号, 商品番号): | 倉庫番号 | 商品番号 | 在庫数 |

ア SELECT 商品番号 FROM 在庫 WHERE EXISTS (SELECT 商品番号 FROM 商品)
イ SELECT 商品番号 FROM 在庫 WHERE NOT EXISTS (SELECT 商品番号 FROM 商品)
ウ SELECT 商品番号 FROM 商品 WHERE EXISTS (SELECT 商品番号 FROM 在庫 WHERE 商品.商品番号 = 在庫.商品番号)
エ SELECT 商品番号 FROM 商品 WHERE NOT EXISTS (SELECT 商品番号 FROM 在庫 WHERE 商品.商品番号 = 在庫.商品番号)

出典:平成26年度 春期 基本情報技術者試験 午前 問28

解き方と答えを見る
  1. 元の SQL の意味:商品表の商品番号のうち、在庫表に1件も無いもの。
  2. 主問合せ(外側の SELECT)は『商品』表でなければならない → 在庫表を主問合せにしたア・イは除外。
  3. 残るウ・エはどちらも相関条件 商品.商品番号 = 在庫.商品番号 を持つ。
  4. 『在庫に無い』のは対応する行が0行のときなので NOT EXISTS → エ。ウ(EXISTS)は在庫がある商品になり、逆の結果。

答え:エ

要点(試験直前に読む)

  • AND は絞り込み、OR は広げる。優先順位は NOT → AND → OR。「どの〜も」は AND。
  • 平均 ≥ 基準 は 合計 ≥ 基準×個数 に直す。千円などの単位も必ずそろえる。
  • 2つの表を並べたら WHERE に「結合条件 AND 絞り込み条件」。結合条件が無いと直積になる。
  • どちらか一方だけ=(A OR B) AND NOT (A AND B)。X AND NOT X は常に偽。
  • LIKE:%は0文字以上、_は1文字。「含む」は '%語%'。ひらがなとカタカナは別の文字。
  • IN(a,b) = = a OR = b。NOT IN = 相関条件付きの NOT EXISTS。BETWEEN は両端を含む範囲。

ひっかけ

  • 括弧の無い OR と AND の混在:AND が先に計算されるので、意図とは違う条件になる。括弧の位置を必ず確認する。
  • IN の書き換えに AND・INTERSECT・BETWEEN が並ぶ:AND と INTERSECT は0行、BETWEEN は間の値(M003)まで拾う。正解は OR。
  • LIKE の % の位置:'UNIX%' は前方一致、'%UNIX' は後方一致。「含む」なら両側に %。カタカナの『メン』をひらがなの『めん』に含めない。
  • EXISTS の選択肢:主問合せの表が逆になっていないか、相関条件(外側の表.列 = 内側の表.列)があるか、EXISTS と NOT EXISTS が逆になっていないかの3点を確認する。
  • 実行結果を問う問題:> と >= を読み違えない(在庫数10は『> 10』を満たさない)。CASE 式は行を減らさないので、外側の表の行数がそのまま出る。

用語(18)

WHERE句 ウェアく
表の各行に条件を当てはめ、真になった行だけを残す SQL の部分。
⚠ HAVING句はグループ化した後の集計結果に条件を付ける。行を絞るなら WHERE。
AND アンド(論理積)
両方の条件が真のときだけ真になる結合で、行を絞り込む。
⚠ OR と逆。「どの〜も」「すべて」は AND。AND は OR より先に計算される。
OR オア(論理和)
どちらかの条件が真なら真になる結合で、残る行を広げる。
⚠ AND と取り違えると条件がゆるくなりすぎる。同じ列の = を OR でつなぐと IN と同じになる。
NOT ノット(否定)
条件の真と偽を反転させる演算子。
⚠ NOT (A AND B) は「両方真ではない」で、「両方偽」ではない。
演算子の優先順位 えんざんしのゆうせんじゅんい
NOT → AND → OR の順に計算されるという決まり。
⚠ 括弧の無い X OR Y AND Z は X OR (Y AND Z) と解釈される。
排他的論理和 はいたてきろんりわ(XOR:Exclusive OR)
2つの条件のどちらか一方だけが真のときに真になる論理演算。
⚠ OR は両方真でも真になる。XOR は (A OR B) AND NOT (A AND B)。
LIKE ライク
% や _ を使い、文字列が指定したパターンに当てはまるかを判定する述語。
⚠ = は完全一致。LIKE でも % を付けなければ完全一致と同じになる。
%(パーセント) パーセント(ワイルドカード)
LIKE で、0文字以上の任意の文字列を表す記号。
⚠ _ はちょうど1文字。前に付ければ後方一致、後ろに付ければ前方一致、両側なら部分一致。
_(アンダースコア) アンダースコア(ワイルドカード)
LIKE で、任意の1文字を表す記号。
⚠ % は0文字以上の任意の長さ。
IN イン
列の値が、一覧または副問合せの結果のどれかに等しければ真になる述語。
⚠ = を OR でつないだものと等価。AND や BETWEEN とは異なる。
BETWEEN ビトウィーン
値が下限以上・上限以下の範囲に入れば真になる述語で、両端を含む。
⚠ IN は列挙した値だけが対象。BETWEEN は間の値(例:M003)も含む。
副問合せ ふくといあわせ(サブクエリ)
SQL 文の中に括弧で入れた別の SELECT 文で、その結果を条件などに使う。
⚠ 外側の列を参照するものは特に相関副問合せと呼ぶ。
相関副問合せ そうかんふくといあわせ
外側の表の列を参照し、外側の1行ごとに実行し直す副問合せ。
⚠ 相関条件の無い副問合せは1回だけ実行され、全行に同じ結果を返す。
EXISTS / NOT EXISTS イグジスツ / ノットイグジスツ
副問合せが1行以上返せば真になるのが EXISTS、0行なら真になるのが NOT EXISTS。
⚠ NOT EXISTS(相関あり)は NOT IN と同じ結果。相関条件が無いと絞り込めない。
NOT IN ノットイン
列の値が、一覧または副問合せの結果のどれとも等しくなければ真になる述語。
⚠ 相関副問合せを使った NOT EXISTS と等価(NULL が含まれる場合は厳密には異なる)。
直積 ちょくせき
2つの表の全行同士を組み合わせた表で、FROM に表を並べて結合条件を書かないとこうなる。
⚠ 結合(内部結合)は、直積から結合条件を満たす組合せだけを残したもの。
CASE式 ケースしき
WHEN の条件によって、出力する値を切り替える式。
⚠ WHERE と違って、行を減らさない。
INTERSECT インターセクト(積集合)
2つの SELECT 結果の両方に含まれる行だけを返す集合演算。
⚠ UNION は和集合(どちらかに含まれる行)。同じ列に異なる値を求める INTERSECT は0行になる。

このレッスンの過去問

このレッスンで稽古する