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行ずつ条件に代入して真か偽かを確かめるのが確実な解き方です。
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 と考えましょう。
平均の条件は「合計」に直して比べる
過去問では「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 で書く形がこれです。
排他的論理和:「どちらか一方だけ」の書き方
排他的論理和(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」の形を見たら、すぐに候補から外して構いません。
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 が含まれると、厳密には結果が異なります)。
平均4,000万円以上・各期3,000万円以上を SQL にする
| 番号 | 名前 | 第 1 期 | 第 2 期 | 第 3 期 | 第 4 期 |
|---|---|---|---|---|---|
| 123 | 山田 一郎 | 29,600 | 31,900 | 36,600 | 41,500 |
| 594 | 鈴木 太郎 | 43,500 | 45,300 | 30,400 | 46,400 |
| 612 | 佐藤 花子 | 49,600 | 39,400 | 42,300 | 51,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
解き方と答えを見る
- 単位をそろえる:表は千円単位なので、4,000万円=40,000千円、3,000万円=30,000千円。
- 平均の条件を合計に直す:(第1期+第2期+第3期+第4期) ÷ 4 ≥ 40,000 → 両辺に4を掛けて、合計 ≥ 160,000。
- 「どの期でも3,000万円以上」は4つすべてを満たすので AND:第1期 ≥ 30000 AND 第2期 ≥ 30000 AND 第3期 ≥ 30000 AND 第4期 ≥ 30000。
- 2つの条件も両方必要なので AND で結ぶ → エ。
- 検算(山田さん):合計=29,600+31,900+36,600+41,500=139,600 < 160,000、第1期も29,600 < 30,000 なので残らない。佐藤さんは合計182,400 ≥ 160,000 で、各期とも30,000以上なので残る。
- 他の選択肢を消す:アは OR で条件がゆるすぎる。イは合計を40,000と比べている(平均の基準のまま)。ウは OR と AND が混在していて、AND が先に計算されるため意図と違う条件になる。
答え:エ(合計 ≥ 160000 AND 各期 ≥ 30000 を4つとも AND)
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
解き方と答えを見る
- 条件①:LIKE '%めん' = 末尾がひらがなの『めん』。
- 1行ずつ確認:ラーメン(カタカナ『メン』→×)、きしめん(○)、チャーシューメン(カタカナ→×)、おかめうどん(『うどん』で終わる→×)、そうめん(○)、それ以外も×。
- 条件①で残るのは、きしめん(130・285円)とそうめん(307・350円)。
- 条件②:単価 < 330。きしめん 285 < 330 →○、そうめん 350 < 330 →×。
- AND なので両方を満たす行だけが残る → 商品番号130のみ。
答え:ウ(130 のみ)
「1教科だけ平均以上」を AND/OR/NOT で表す
ア 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
解き方と答えを見る
- 求めたいのは「A と B のどちらか一方だけが真」=排他的論理和。
- 「少なくとも一方が真」は A OR B。
- 「両方が真ではない」は NOT (A AND B)。
- 2つを同時に満たす必要があるので AND で結ぶ:(A OR B) AND NOT (A AND B) → ウ。
- ア・エは『X AND NOT X』の形で常に偽。イは A AND B が真(両方真)のとき NOT (A OR B) が必ず偽になるので、これも常に偽。
答え:ウ
CASE 式の中の IN 副問合せの実行結果
| 部品ID | 部品名 |
|---|---|
| 01 | メモリ |
| 02 | ディスプレイ |
| 03 | ディスク |
| 04 | マウス |
| 05 | キーボード |
| 場所 | 部品ID | 在庫数 |
|---|---|---|
| 東京 | 01 | 10 |
| 東京 | 03 | 20 |
| 東京 | 04 | 20 |
| 大阪 | 02 | 25 |
| 大阪 | 04 | 30 |
ア [図] 表(部品名/東京/大阪): ディスプレイ ×/○,ディスク ○/×,マウス ○/○
イ [図] 表(部品名/東京/大阪): メモリ ×/×,ディスプレイ ×/○,ディスク ○/×,マウス ○/○
ウ [図] 表(部品名/東京/大阪): メモリ ×/×,ディスプレイ ×/○,ディスク ○/×,マウス ○/○,キーボード ×/×
エ [図] 表(部品名/東京/大阪): メモリ ×/×,ディスプレイ ×/○,ディスク ×/×,マウス ○/○,キーボード ×/×
出典:基本情報技術者試験 科目A免除 修了試験 20260726 実施分 問20
解き方と答えを見る
- 東京の副問合せ:場所='東京' AND 在庫数 > 10 → 03(20)と04(20)。01は在庫数10で『> 10』を満たさない。結果は {03, 04}。
- 大阪の副問合せ:場所='大阪' AND 在庫数 > 10 → 02(25)と04(30)。結果は {02, 04}。
- 外側は FROM 部品 で WHERE が無いので、部品の5行がすべて結果に出る(CASE は値を切り替えるだけで、行を減らさない)。
- 各部品を判定:メモリ01(東京×・大阪×)、ディスプレイ02(×・○)、ディスク03(○・×)、マウス04(○・○)、キーボード05(×・×)。
- 5行で、この並びになっている選択肢 → ウ。ア・イは行数が足りない。エはディスクの東京が×になっている。
答え:ウ
NOT IN を NOT EXISTS に書き換える
ア 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 商品.商品番号 = 在庫.商品番号)
解き方と答えを見る
- 元の SQL の意味:商品表の商品番号のうち、在庫表に1件も無いもの。
- 主問合せ(外側の SELECT)は『商品』表でなければならない → 在庫表を主問合せにしたア・イは除外。
- 残るウ・エはどちらも相関条件 商品.商品番号 = 在庫.商品番号 を持つ。
- 『在庫に無い』のは対応する行が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)
表の各行に条件を当てはめ、真になった行だけを残す SQL の部分。
⚠ HAVING句はグループ化した後の集計結果に条件を付ける。行を絞るなら WHERE。
両方の条件が真のときだけ真になる結合で、行を絞り込む。
⚠ OR と逆。「どの〜も」「すべて」は AND。AND は OR より先に計算される。
どちらかの条件が真なら真になる結合で、残る行を広げる。
⚠ AND と取り違えると条件がゆるくなりすぎる。同じ列の = を OR でつなぐと IN と同じになる。
条件の真と偽を反転させる演算子。
⚠ NOT (A AND B) は「両方真ではない」で、「両方偽」ではない。
NOT → AND → OR の順に計算されるという決まり。
⚠ 括弧の無い X OR Y AND Z は X OR (Y AND Z) と解釈される。
2つの条件のどちらか一方だけが真のときに真になる論理演算。
⚠ OR は両方真でも真になる。XOR は (A OR B) AND NOT (A AND B)。
% や _ を使い、文字列が指定したパターンに当てはまるかを判定する述語。
⚠ = は完全一致。LIKE でも % を付けなければ完全一致と同じになる。
LIKE で、0文字以上の任意の文字列を表す記号。
⚠ _ はちょうど1文字。前に付ければ後方一致、後ろに付ければ前方一致、両側なら部分一致。
LIKE で、任意の1文字を表す記号。
⚠ % は0文字以上の任意の長さ。
列の値が、一覧または副問合せの結果のどれかに等しければ真になる述語。
⚠ = を OR でつないだものと等価。AND や BETWEEN とは異なる。
値が下限以上・上限以下の範囲に入れば真になる述語で、両端を含む。
⚠ IN は列挙した値だけが対象。BETWEEN は間の値(例:M003)も含む。
SQL 文の中に括弧で入れた別の SELECT 文で、その結果を条件などに使う。
⚠ 外側の列を参照するものは特に相関副問合せと呼ぶ。
外側の表の列を参照し、外側の1行ごとに実行し直す副問合せ。
⚠ 相関条件の無い副問合せは1回だけ実行され、全行に同じ結果を返す。
副問合せが1行以上返せば真になるのが EXISTS、0行なら真になるのが NOT EXISTS。
⚠ NOT EXISTS(相関あり)は NOT IN と同じ結果。相関条件が無いと絞り込めない。
列の値が、一覧または副問合せの結果のどれとも等しくなければ真になる述語。
⚠ 相関副問合せを使った NOT EXISTS と等価(NULL が含まれる場合は厳密には異なる)。
2つの表の全行同士を組み合わせた表で、FROM に表を並べて結合条件を書かないとこうなる。
⚠ 結合(内部結合)は、直積から結合条件を満たす組合せだけを残したもの。
WHEN の条件によって、出力する値を切り替える式。
⚠ WHERE と違って、行を減らさない。
2つの SELECT 結果の両方に含まれる行だけを返す集合演算。
⚠ UNION は和集合(どちらかに含まれる行)。同じ列に異なる値を求める INTERSECT は0行になる。
このレッスンの過去問
- SQLのWHERE句による複合条件(AND条件)平成23年度 特別試験 基本情報技術者試験 午前 問30
- 排他的論理和をAND/OR/NOTで表すWHERE条件基本情報技術者試験 科目A免除 修了試験 20250608 実施分 問20
- SQLのLIKE述語によるパターンマッチ(%)平成25年度 春期 基本情報技術者試験 午前 問29
- SQLのIN条件とOR条件の等価性令和7年度 基本情報技術者試験 科目A 公開問題 問6
- SQLのNOT INとNOT EXISTSの等価性平成26年度 春期 基本情報技術者試験 午前 問28