結合の概念と構文について

完了

複数のテーブルのデータを結合する最も基本的で一般的な方法は、JOIN 操作を使用することです。 JOIN を SELECT ステートメントの独立した句と考える人もいますが、FROM 句の一部と考える人もいます。 このモジュールでは、主に FROM 句の一部であると見なします。 このモジュールでは、T-SQL SELECT ステートメントの FROM 句により、クエリの後のフェーズで使用される中間仮想テーブルを作成する方法について説明します。

FROM 句と仮想テーブル

SQL Server でクエリが処理されるときに実行される操作の論理的順序について学習したことがあれば、SELECT ステートメントの FROM 句が最初に処理されるのを見たことがあるはずです。 この句により、クエリの行のソースとなるテーブルが決定されます。 FROM では、1 つのテーブルを参照したり、複数のテーブルをクエリのデータ ソースとしてまとめたりすることができます。 FROM 句は、仮想テーブルを作成して設定するものと考えることができます。 この仮想テーブルは、FROM 句の出力を保持し、後で適用される SELECT ステートメントの句 (WHERE 句など) によって使用されます。 FROM 句に結合演算子などの追加の機能を追加するときは、FROM 句の要素の目的を、仮想テーブルへの行の追加または仮想テーブルからの行の削除と考えると便利です。

FROM 句によって作成される仮想テーブルは、論理エンティティのみです。 SQL Server では、FROM 句の結果を保持するために、永続的または一時的にかかわらず物理テーブルは作成されません。これは WHERE 句またはクエリのその他の部分に渡されます。

FROM 句によって作成された仮想テーブルには、結合されたすべてのテーブルのデータが含まれています。 結果を "セット" と考え、結合の結果をベン図ととらえるとわかりやすいかもしれません。

A Venn diagram showing the set of an Employee table joined to a SalesOrder table

その履歴全体を通じて、T-SQL 言語は、SQL 言語の米国国家規格協会 (ANSI) 標準に対する変更を反映するように拡張されています。 これらの変更が示される最も重要な場所の 1 つは、FROM 句内の結合の構文です。 ANSI SQL-89 標準では、FROM 句に複数のテーブルをコンマ区切りのリストとして含めることで、結合が指定されました。 含める行を決定するすべてのフィルター処理は、次のように WHERE 句で実行されました。

SELECT p.ProductID, m.Name AS Model, p.Name AS Product
FROM SalesLT.Product AS p, SalesLT.ProductModel AS m
WHERE p.ProductModelID = m.ProductModelID;

この構文は SQL Server で引き続きサポートされますが、複雑な結合のフィルターを表すのが煩雑になるため、推奨されません。 さらに、WHERE 句が誤って省略された場合、ANSI SQL-89 スタイルの結合はデカルト積になりやすく、過度の数の結果行が返されて、パフォーマンスの問題が発生します。また、結果が不正になるおそれがあります。

T-SQL での複数テーブル クエリの記述について学習する場合は、デカルト積の概念を理解しておくことが重要です。 数学では、デカルト積は 2 つのセットの積です。 2 つの要素のセットと 6 つの要素のセットの積は、12 個の要素 (6 x 2) のセットです。 一方のセット内のすべての要素は、他方のセット内のすべての要素と組み合わされます。 次の例では、2 つの要素を持つ名前のセットと、3 つの要素を持つ製品のセットがあります。 デカルト積により、すべての名前とすべての積が組み合わされて、6 つの要素が生成されます。

Cartesian product

データベースでは、デカルト積は、あるテーブルのすべての行を別のテーブルのすべての行と組み合わせた結果です。 10 行のテーブルと 100 行のテーブルの積は、1,000 行の結果セットです。 JOIN 操作の基になる結果はデカルト積ですが、ほとんどの T-SQL クエリでは、デカルト積は望ましい結果では "されません"。 T-SQL では、デカルト積は、2 つの入力テーブル間のリレーションシップを考慮せずにそれらのテーブルが結合された場合に発生します。 リレーションシップに関する情報がない場合、SQL Server クエリ プロセッサにより、可能なすべての行の組み合わせが返されます。 この結果には、テスト データの生成など、実用的なアプリケーションがいくつか含まれる場合があります。しかし、一般的には有用ではなく、パフォーマンスに重大な影響を与えるおそれがあります。

ANSI SQL-92 標準の導入により、キーワード JOIN 句および ON 句のサポートが追加されました。 この構文は T-SQL でもサポートされています。 結合は、FROM 句で適切な JOIN 演算子を使用して表されます。 フィルター述語になるテーブル間の論理リレーションシップは、ON 句で指定されます。

次の例では、前のクエリを新しい構文で再記述しています。

SELECT p.ProductID, m.Name AS Model, p.Name AS Product
FROM SalesLT.Product AS p
JOIN SalesLT.ProductModel AS m
    ON p.ProductModelID = m.ProductModelID;

注意

ANSI SQL-92 構文を使用すると、デカルト積が誤って生成されることが少なくなります。 キーワード JOIN を追加すると、JOIN が CROSS JOIN として指定されていない限り、ON 句がない場合に構文エラーが発生します。