― INNER / LEFT JOIN と「WHERE 右側 IS NULL」で存在しないデータを抽出する実戦ガイド ―
SQL Server の JOIN は、文章だけで覚えようとすると難しく感じます。 しかし 図でイメージできるようになると、一気に理解が進みます。
この記事では、JOIN の中でも特に重要な
- INNER JOIN(共通部分だけ)
- LEFT JOIN(左を全部返す)
- LEFT JOIN + WHERE 右側 IS NULL(存在しないデータを抽出)
を 2テーブルだけで徹底的に理解します。
1. 今回使うテーブル(2つだけで十分)
JOIN の本質は、2テーブルあれば完全に理解できます。以下のテーブルを作っておきます。
✔ Customers(顧客マスタ)
CREATE TABLE Customers (
CustomerID INT NOT NULL PRIMARY KEY,
Name NVARCHAR(100) NOT NULL
);
✔ Orders(注文テーブル)
CREATE TABLE Orders (
OrderID INT NOT NULL PRIMARY KEY,
CustomerID INT NOT NULL,
Amount INT NOT NULL,
CONSTRAINT FK_Orders_Customers
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID));2. サンプルデータを投入する
INSERT INTO Customers (CustomerID, Name) VALUES
(1, 'Alice'),
(2, 'Bob'),
(3, 'Carol'); -- 注文がない顧客
INSERT INTO Orders (OrderID, CustomerID, Amount) VALUES
(101, 1, 500),
(102, 1, 300),
(103, 2, 200);
これで、
- Alice:注文あり
- Bob:注文あり
- Carol:注文なし
という状態が作れます。
3. JOIN の「左」と「右」はどこで決まる?
JOIN を理解するうえで最重要ポイントはこれです。
FROM Customers c -- 左
LEFT JOIN Orders o -- 右イメージ的にはこんな感じ。
LEFT TABLE(左) = FROM の表
RIGHT TABLE(右) = JOIN の表このルールを理解すると、JOIN の挙動が一気にクリアになります。
4. INNER JOIN のイメージ
― 共通部分だけを取り出す JOIN ―
INNER JOIN は 両方の表に存在するデータだけを返します。
イメージ
Customers ●●●
●●● Orders
(重なった部分だけ)💻 SQL
SELECT
c.CustomerID,
c.Name,
o.OrderID,
o.Amount
FROM Customers c
INNER JOIN Orders o
ON c.CustomerID = o.CustomerID;

🧪 結果
Carol(CustomerID=3)は注文がないため 除外 されます。
INNER JOIN は 「共通部分だけ欲しい」 ときに使います。
5. LEFT JOIN のイメージ
― 左を全部返し、右は一致した分だけ返す JOIN ―
LEFT JOIN は INNER JOIN と違い、
左表は必ず返す。右表は一致した行だけ返す。 一致しない場合は右側が NULL になる。
イメージ
LEFT TABLE(左) ●●●●● ← 全部返す
RIGHT TABLE(右) ●●● ← 一致した分だけ
左にあって右にない部分 → 右側が NULL💻 SQL
SELECT
c.CustomerID,
c.Name,
o.OrderID,
o.Amount
FROM Customers c
LEFT JOIN Orders o
ON c.CustomerID = o.CustomerID;
🧪 結果
Carol の行が NULL 付きで残る のがポイント。
6. LEFT JOIN + WHERE 右側 IS NULL
― 存在しないデータを抽出する最強パターン ―
ここからが実務で最も重要な部分です。
✔ 結論
LEFT JOIN + WHERE 右側 IS NULL → 左にはあるが右には存在しないデータを抽出する
LEFT JOIN によって右側が NULL になった行を WHERE で絞り込むだけです。
7. 注文が一度もない顧客を抽出する SQL
SELECT
c.CustomerID,
c.Name
FROM Customers c
LEFT JOIN Orders o
ON c.CustomerID = o.CustomerID
WHERE o.OrderID IS NULL;
8. なぜ NULL で判定するのか?
LEFT JOIN の仕様はこうです。
- 左表は必ず返す
- 右表に一致がないと 右側が NULL になる
だから、
WHERE o.OrderID IS NULL → 右表に一致がなかった行だけを抽出
という仕組みになります。
9. INNER JOIN と LEFT JOIN の違いを一発で理解する表
| JOIN | 左表 | 右表 | NULL | 主な用途 |
|---|---|---|---|---|
| INNER | 一致した行のみ | 一致した行のみ | 出ない | 共通部分だけ欲しい |
| LEFT | 全部 | 一致した行のみ | 右側に出る | 存在しないデータの検出 |
10. 実務でのよくある用途(2テーブルで完結)
✔ 1. マスタに存在するのに、トランザクションに無いデータ
SELECT c.CustomerID, c.Name
FROM Customers c
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID
WHERE o.OrderID IS NULL;
✔ 2. 未登録チェック
- 顧客マスタにいるのに注文がない
- 商品マスタにあるのに売上がない
- 社員マスタにいるのに勤怠がない
全部これで取れます。
11. まとめ
- JOIN の左右は FROM が左、JOIN が右
- INNER JOIN は「共通部分だけ」
- LEFT JOIN は「左は全部、右は一致した分だけ」
- 一致しない行は右側が NULL
- WHERE 右側 IS NULL で「右にない行だけ」を抽出
- 実務では未登録チェック・差分チェックで超よく使う

コメント