SQLの基礎はわかっているのに、試験の設問になると「どっちが基点?」「この列はGROUP BYに入れる?」などで迷う――そんな受験者がつまずきやすいポイントを、実務と試験の両面から整理します。本記事では、JOINの左右、外部キーで読む多重度、GROUP BYとSELECTの関係、エイリアスの直感的な把握と記法、主キーが多い(複合主キー)ケースの5テーマを、最短で腑に落ちるように解説します。
目次
1. JOINのON句:左右に区別はあるのか?
結論
- INNER JOIN:
ON
の左右(A.id = B.id
とB.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
直感的に把握するコツ
- FROM句やJOIN句の直後を探せば「どのテーブルに付いているか」が分かる
- 列を参照している箇所で「R.列名」とあれば、まずFROM句に「... R」がないか探す
- テーブル名が長い場合や複数JOINする場合に、短縮形のアルファベットで付けられることが多い
5. 主キーが多い場合について
複合主キーとは?
主キーは「行を一意に識別する最小の列の組合せ」です。1列で足りないときは、複数列を組み合わせた複合主キーになります。
典型例
- 注文詳細:
注文ID + 商品ID
が主キー。どちらか1つだけでは一意にならない。 - 月次集計表:
年月 + 駐車場ID + 車種ID + 会員ID
が主キー。1行が「特定の月・駐車場・車種・会員」を表すため。
実務と試験の違い
- 実務では列数が多い複合キーは扱いにくいため、代理キー(サロゲートキー)を追加することも多い
- 試験では「そのテーブルの1行がどの粒度を表しているか」を基準に、必要な列をすべて組み合わせればOK
覚え方
「1行=何を表すのか(粒度)」を考えると、自ずと主キーの列が見えてくる、と覚えると迷いません。