IPA|情報処理技術者試験

応用情報技術者試験に出るSQLの落とし穴5選:JOIN・外部キー・GROUP BY・エイリアス・複合主キーの理解法

SQLの基礎はわかっているのに、試験の設問になると「どっちが基点?」「この列はGROUP BYに入れる?」などで迷う――そんな受験者がつまずきやすいポイントを、実務と試験の両面から整理します。本記事では、JOINの左右外部キーで読む多重度GROUP BYとSELECTの関係エイリアスの直感的な把握と記法主キーが多い(複合主キー)ケースの5テーマを、最短で腑に落ちるように解説します。


1. JOINのON句:左右に区別はあるのか?

結論

  • INNER JOINONの左右(A.id = B.idB.id = A.id)に意味の違いはありません(等号は対称)。
  • OUTER JOIN(LEFT/RIGHT/FULL)ONの左右ではなく、JOIN句の左右(LEFT/RIGHTでどちらを「必ず残すか」)が結果を決めます。
  • 非等号結合(<, >, BETWEEN など):左右を入れ替えると意味が変わるので注意。

基本例:INNER JOIN は左右入れ替え可

-- 同じ意味
SELECT *
FROM A
JOIN B ON A.id = B.id;

SELECT *
FROM A
JOIN B ON B.id = A.id;

等号の比較は対称なので、結果は同一です。可読性の観点では「左テーブルの列は左、右テーブルの列は右」に揃えるのが一般的です。

LEFT/RIGHT で結果が変わる(基点はJOINの左右)

-- A を基点に「AにあるがBにない行」も残す
SELECT A.id, B.name
FROM A
LEFT JOIN B ON A.id = B.id;

-- B を基点に「BにあるがAにない行」も残す
SELECT A.id, B.name
FROM A
RIGHT JOIN B ON A.id = B.id;

基点(必ず残る側)LEFT JOIN の左、RIGHT JOIN の右です。ONの左右ではなく、JOINの方向で決まる点を取り違えないようにしましょう。

非等号結合は左右で意味が変わる

-- A.value が B.value より小さい行の組合せ
SELECT *
FROM A
JOIN B ON A.value < B.value;

-- ↑とは意味が逆
SELECT *
FROM A
JOIN B ON B.value < A.value;

大小比較は対称ではありません。設問で出てきた場合は「どちらを基準にするのか」をしっかり読み取ることが重要です。

2. エンティティ関連の見分け方:外部キーに注目

基本ルール

  • 外部キーを持つ側が「多(N)」
  • 外部キーが参照する主キー側が「一(1)」

例えば「社員」と「部署」の場合、社員テーブルが部署IDを外部キーとして持っています。社員は複数人が同じ部署に所属できるので、関係は「部署 1:社員 N」となります。

部署(部署ID 主キー)
社員(社員ID 主キー, 部署ID 外部キー)

この場合、部署IDを持つ「社員」が多(N)、参照される「部署」が一(1)です。

例外パターン

  • 複合キー:注文詳細のように「注文ID+商品ID」で一意にする場合、それぞれの外部キーを個別に考える。
  • 自己参照:社員表に「上司ID」を持たせる場合、社員:社員で1:Nの関係が生まれる。
  • 多対多(M:N):学生と講義の関係は中間テーブル(受講)を作って1:N+1:Nに分解する。
  • 概念ER図:問題文では外部キーが図示されず、文章から1:Nを読み取る必要があることもある。

したがって「外部キーを持っている方が多」というルールでほとんど解けますが、例外を押さえておくと試験で迷いにくくなります。


3. GROUP BYで指定する列の決め方

基本ルール

  • SELECT句に書いた列は、集計関数を使っていない場合はすべてGROUP BYに含める必要がある
  • 集計関数を使った列(COUNT, SUM, MAXなど)はGROUP BYに含める必要なし
-- 部署ごとの社員数
SELECT 部署ID, COUNT(*)
FROM 社員
GROUP BY 部署ID;   -- 部署IDは非集計列なのでGROUP BY必須

GROUP BYの粒度による違い

-- 部署ごと
SELECT 部署ID, COUNT(*)
FROM 社員
GROUP BY 部署ID;

-- 部署 × 役職ごと
SELECT 部署ID, 役職, COUNT(*)
FROM 社員
GROUP BY 部署ID, 役職;

-- 部署 × 役職 × 社員ごと(意味が薄い)
SELECT 部署ID, 役職, 社員ID, COUNT(*)
FROM 社員
GROUP BY 部署ID, 役職, 社員ID;

すべての列をGROUP BYに入れると「行単位」でしかまとまらないので、COUNT(*)は必ず1になり、集計の意味がなくなります。

DISTINCTとの関係

実は「全列をGROUP BYする」と「DISTINCT」と同じ効果になります。

-- 社員の部署IDと役職の組み合わせを一意に取りたい場合
SELECT DISTINCT 部署ID, 役職 FROM 社員;

-- GROUP BYでも同じ
SELECT 部署ID, 役職 FROM 社員 GROUP BY 部署ID, 役職;

つまり、GROUP BYは集計にも重複排除にも使えるということです。

4. エイリアスを直感的に把握する方法と記載ルール

エイリアスとは?

テーブルや列に一時的な別名を付ける仕組みです。SQLの問題文ではいきなり R.列名J.列名 のように登場することがありますが、これはFROM句やJOIN句で設定されたエイリアスを指しています。

記載ルール

  • テーブルにエイリアスを付けるテーブル名 エイリアスASは省略可)
    例:FROM 社員 E (社員テーブルを E として参照)
  • サブクエリにエイリアスを付ける:必須。
    例:FROM (SELECT ... FROM 社員) S
  • 列や式にエイリアスを付ける列名/式 AS 別名(AS省略可)
    例:SELECT COUNT(*) AS 件数
  • 参照時:必ず エイリアス.列名 の順で書く
    例:SELECT E.社員名 FROM 社員 E

直感的に把握するコツ

  1. FROM句やJOIN句の直後を探せば「どのテーブルに付いているか」が分かる
  2. 列を参照している箇所で「R.列名」とあれば、まずFROM句に「... R」がないか探す
  3. テーブル名が長い場合や複数JOINする場合に、短縮形のアルファベットで付けられることが多い

5. 主キーが多い場合について

複合主キーとは?

主キーは「行を一意に識別する最小の列の組合せ」です。1列で足りないときは、複数列を組み合わせた複合主キーになります。

典型例

  • 注文詳細注文ID + 商品ID が主キー。どちらか1つだけでは一意にならない。
  • 月次集計表年月 + 駐車場ID + 車種ID + 会員ID が主キー。1行が「特定の月・駐車場・車種・会員」を表すため。

実務と試験の違い

  • 実務では列数が多い複合キーは扱いにくいため、代理キー(サロゲートキー)を追加することも多い
  • 試験では「そのテーブルの1行がどの粒度を表しているか」を基準に、必要な列をすべて組み合わせればOK

覚え方

「1行=何を表すのか(粒度)」を考えると、自ずと主キーの列が見えてくる、と覚えると迷いません。

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