2025年10月9日木曜日

SQL Server JOINの基本構文と種類ごとの使い分け

SQL Serverで理解しておきたいJOIN構文と種類ごとの使い分け

JOINは、複数のテーブルを結合して一つの結果セットにまとめるための構文です。
リレーショナルデータベースの基本かつ中心的な機能であり、業務データ分析やアプリケーション開発でも頻繁に使用されます。
本記事では、JOINの種類と使い分け、そして実務で役立つ注意点を実例付きで詳しく解説します。

目次

JOINとは

JOINは、異なるテーブル間の関連性(キー列)をもとに結合し、複数テーブルを1つの結果として扱うSQL構文です。
リレーショナルデータベースでは、テーブルを正規化することで冗長性を減らしていますが、JOINはそれらを再び論理的にまとめるための仕組みです。
SQL Serverでは、主に INNER / LEFT / RIGHT / FULL / CROSS の5種類が提供されています。

INNER JOIN(内部結合)

INNER JOINは「両方のテーブルに共通して存在するデータ」だけを取り出す結合です。
もっとも一般的で、基礎となるJOINの形です。


-- INNER JOIN の基本構文
SELECT o.OrderId, c.FullName
FROM dbo.Orders AS o
INNER JOIN dbo.Customers AS c
  ON o.CustomerId = c.CustomerId;

この例では、顧客テーブルと注文テーブルを顧客IDで結合し、両方に存在するデータのみを取得します。

🔹 実務例:社員と部署を結合して一覧を表示


SELECT e.EmployeeId, e.FullName, d.DepartmentName
FROM dbo.Employees AS e
INNER JOIN dbo.Departments AS d
  ON e.DepartmentId = d.DepartmentId
ORDER BY d.DepartmentName;

INNER JOINでは「結合条件(ON)」と「絞り込み条件(WHERE)」を分けて記述するのがベストプラクティスです。
可読性と保守性が高まり、他のJOIN構文でも統一した書き方ができます。

LEFT / RIGHT OUTER JOIN(外部結合)

OUTER JOINは、一方のテーブルに存在しないデータも含めたい場合に使います。
LEFTは左側テーブルを基準に、RIGHTは右側を基準にします。

ONとWHEREの位置による違い


-- ON に条件を書く(NULLを保持)
SELECT c.CustomerId, c.FullName, o.OrderId
FROM dbo.Customers AS c
LEFT JOIN dbo.Orders AS o
  ON c.CustomerId = o.CustomerId
  AND o.Region = 'Tokyo';

-- WHERE に条件を書く(NULLは除外される)
SELECT c.CustomerId, c.FullName, o.OrderId
FROM dbo.Customers AS c
LEFT JOIN dbo.Orders AS o
  ON c.CustomerId = o.CustomerId
WHERE o.Region = 'Tokyo';

前者は「東京の注文がある顧客は結合、ない場合はNULL」を返し、
後者は「東京以外の顧客が除外」されます。
この違いを理解していないと、OUTER JOINの意味が変わってしまうので要注意です。

比較イメージ

条件の書き方結果の特徴NULL保持
ON に条件を書く結合条件に合わない右側行は NULL として保持保持される
WHERE に条件を書くWHERE で絞り込まれるため、NULL行は除外除外される

アンチ結合(存在しないデータを抽出)

LEFT JOINとIS NULLを組み合わせることで、「関連データが存在しない行」を抽出できます。
これは アンチ結合 と呼ばれ、実務で頻出するパターンです。


-- 注文が存在しない顧客を抽出
SELECT c.CustomerId, c.FullName
FROM dbo.Customers AS c
LEFT JOIN dbo.Orders AS o
  ON c.CustomerId = o.CustomerId
WHERE o.CustomerId IS NULL;

この構文は「未注文の顧客」「未処理の申請」など、業務システムでよく使われます。

FULL OUTER JOIN(全結合)

FULL OUTER JOINは、両方のテーブルを結合し、どちらか一方にしか存在しないデータも含めます。
両テーブルの差分確認やデータ同期チェックで活躍します。


SELECT a.KeyId, a.Value AS LeftValue, b.Value AS RightValue
FROM dbo.TableA AS a
FULL OUTER JOIN dbo.TableB AS b
  ON a.KeyId = b.KeyId;

NULLを多く含むため、実務では「差分検出」など限定的な用途に使われます。

CROSS JOIN(直積結合)

CROSS JOINは、両テーブルの全行を掛け合わせた結果を返します。
行数が「左×右」となるため、意図せず使うとデータが爆発的に増える点に注意が必要です。


SELECT e.FullName, p.ProductName
FROM dbo.Employees AS e
CROSS JOIN dbo.Products AS p;

意図的に使うケースとしては、カレンダーテーブルと商品リストを組み合わせて「販売予定表」を生成するなどがあります。

JOIN省略記法と注意点

旧来のSQLではFROM句でカンマ区切りにし、WHERE句で結合条件を書く方法がありました。


SELECT *
FROM dbo.Orders AS o, dbo.Customers AS c
WHERE o.CustomerId = c.CustomerId;

しかし、可読性と保守性の観点から、現在ではANSI JOIN構文(INNER/LEFTなど)を使用することが推奨されています。
複数テーブルを扱う際、カンマ区切り構文では誤結合(クロス結合化)のリスクが高くなります。

実務での注意点

  • ON句とWHERE句の役割を明確に分ける:結合条件と抽出条件を混在させない。
  • 多対多のJOINは重複行に注意:意図せず行数が増える場合は DISTINCT または集約を検討。
  • インデックスを活用:結合キーにインデックスを付与するとパフォーマンスが向上。
  • NULL比較の落とし穴:JOIN条件にNULLが絡む場合は IS NULL / IS NOT NULL を明示。
  • 実行計画の確認:複雑なJOINはSQL Server Management Studioの実行計画で検証する。

実務課題と回答例

以下はJOINを理解するための練習課題です。
それぞれの構文を実際に書いて動作を確認してみましょう。

🔹 課題1:INNER JOINで顧客と注文を結合


-- 回答例
SELECT o.OrderId, c.FullName, o.OrderDate
FROM dbo.Orders AS o
INNER JOIN dbo.Customers AS c
  ON o.CustomerId = c.CustomerId;

🔹 課題2:OUTER JOINで全顧客と注文を一覧化


-- 回答例
SELECT c.CustomerId, c.FullName, o.OrderId
FROM dbo.Customers AS c
LEFT JOIN dbo.Orders AS o
  ON c.CustomerId = o.CustomerId
ORDER BY c.CustomerId;

🔹 課題3:アンチ結合で「注文がない顧客」を抽出


-- 回答例
SELECT c.CustomerId, c.FullName
FROM dbo.Customers AS c
LEFT JOIN dbo.Orders AS o
  ON c.CustomerId = o.CustomerId
WHERE o.CustomerId IS NULL;

🔹 課題4:CROSS JOINで組み合わせを生成


-- 回答例
SELECT e.FullName, p.ProductName
FROM dbo.Employees AS e
CROSS JOIN dbo.Products AS p;

🔹 課題5:3テーブルをJOINして顧客・注文・商品を結合


-- 回答例
SELECT c.FullName, o.OrderId, p.ProductName, o.Quantity
FROM dbo.Customers AS c
INNER JOIN dbo.Orders AS o
  ON c.CustomerId = o.CustomerId
INNER JOIN dbo.Products AS p
  ON o.ProductId = p.ProductId;

まとめ

JOINを使いこなすことで、複数テーブルのデータを自由に組み合わせられます。
- INNER JOIN:共通データの取得
- LEFT / RIGHT OUTER JOIN:片側データを保持
- FULL OUTER JOIN:差分確認に利用
- CROSS JOIN:全組合せを生成
- アンチ結合:存在しないデータを抽出
- 結合条件はONに、絞り込みはWHEREに分けて記述することが重要です。

参考リンク

SQL Server 解説用イメージ

補足:JOIN構文はSQL Serverの全バージョンで共通して使用可能です。
結合数が多いクエリでは、実行計画の確認とインデックス設計がパフォーマンス最適化の鍵になります。

※2025/10/28 更新

0 件のコメント:

コメントを投稿