結合の基礎

結合を使用すると、テーブル間の論理リレーションシップに基づいて、複数のテーブルからデータを取得できます。結合では、Microsoft SQL Server が 1 つのテーブルのデータを使用して別のテーブルの行を選択する方法を指定します。

結合条件は、クエリ内の 2 つのテーブルの関係を定義します。

  • テーブルごとに結合に使用する列を指定します。一般的な結合条件では、1 つのテーブルから外部キーを指定し、他のテーブルでそれに対応したキーを指定します。

  • 列値を比較する論理演算子 (=、<> など) を指定します。

内部結合は、FROM 句または WHERE 句のどちらを使用しても指定できます。外部結合の指定には、FROM 句しか使用できません。結合条件は、検索条件 WHERE と HAVING を使用して、FROM 句で参照されたベース テーブルからどの行を選択するかを指定します。

結合は、FROM 句でも WHERE 句でも指定できます。FROM 句で結合条件を指定すると、WHERE 句で他の検索条件が指定された場合に区別しやすくなります。結合を指定する場合、FROM 句で指定することをお勧めします。次に、簡潔な ISO FROM 句による結合の構文を示します。

FROM first_table join_type second_table [ON (join_condition)]

join_type は、実行する結合の種類 (内部、外部、クロス) を指定します。join_condition は、結合された各行を評価するための述語を定義します。以下に FROM 句での結合指定の例を示します。

FROM Purchasing.ProductVendor JOIN Purchasing.Vendor
     ON (ProductVendor.BusinessEntityID = Vendor.BusinessEntityID)

次の例は、この結合を使用した簡潔な SELECT ステートメントを示します。

SELECT ProductID, Purchasing.Vendor.BusinessEntityID, Name
FROM Purchasing.ProductVendor JOIN Purchasing.Vendor
    ON (Purchasing.ProductVendor.BusinessEntityID = Purchasing.Vendor.BusinessEntityID)
WHERE StandardPrice > $10
  AND Name LIKE N'F%'
GO

この選択により、企業名が F で始まる企業が提供する製品のうち価格が 10 ドルを超えている部品について、製品と納入業者の情報が返されます。

1 つのクエリで複数のテーブルを参照する場合、どの列参照も明確である必要があります。上記の例では、ProductVendor テーブルと Vendor テーブルの両方に、BusinessEntityID という名前の列があります。複数のテーブル間で重複している列名をクエリで参照する場合は、列名をテーブル名で修飾する必要があります。この例では Vendor 列への参照はすべて修飾されています。

クエリで使用する複数のテーブルで列名が重複していない場合、参照する列名にテーブル名を付けて修飾する必要はありません。上記の例を参照してください。このような SELECT ステートメントは、どのテーブルの列か示されていないので、わかりにくいことがあります。すべての列をテーブル名で修飾すれば、クエリは読みやすくなります。テーブル別名を使用すればもっと読みやすくなります。特にテーブル名をデータベース名または所有者名で修飾する必要がある場合は、別名を使用すると読みやすくなります。次の例は、上記の例と同じですが、テーブル別名が割り当てられており、列はテーブル別名で修飾されているので読みやすくなっています。

SELECT pv.ProductID, v.BusinessEntityID, v.Name
FROM Purchasing.ProductVendor AS pv 
JOIN Purchasing.Vendor AS v
    ON (pv.BusinessEntityID = v.BusinessEntityID)
WHERE StandardPrice > $10
    AND Name LIKE N'F%';

上記の例では、FROM 句 (推奨の方法) で結合条件を指定していました。次の例に示すように、これと同じ結合条件を持つクエリを WHERE 句でも指定できます。

SELECT pv.ProductID, v.BusinessEntityID, v.Name
FROM Purchasing.ProductVendor AS pv, Purchasing.Vendor AS v
WHERE pv.VendorID = v.VendorID
    AND StandardPrice > $10
    AND Name LIKE N'F%';

結合の選択リストは、結合されたテーブル内のすべての列を参照することも、一部の列だけを参照することもできます。選択リストには、結合したすべてのテーブルの列を含める必要はありません。たとえば、3 つのテーブルを結合した場合、1 つのテーブルだけを使用して残りの 2 つのテーブルの一方から 3 番目のテーブルにブリッジできます。中央のテーブルの列を選択リストで参照する必要はありません。

結合条件では、通常は等値比較演算子 (=) を使用します。ただし、他の述語と同様に他の比較演算子や関係演算子も指定できます。詳細については、「式における演算子の使用」および「WHERE (Transact-SQL)」を参照してください。

SQL Server で結合を処理する場合、クエリ エンジンは、複数の候補の中から最も効率的な結合の処理方法を選択します。各結合の物理的実行には何種類もの最適化を使用できるので、その実行を確実に予測することはできません。

結合条件で使用する複数の列間で名前やデータ型が同じである必要はありません。ただし、データ型が同じでない場合、互換性があるか SQL Server が暗黙的に変換できるデータ型である必要があります。データ型を暗黙的に変換できない場合、結合条件は CAST 関数を使用してデータ型を明示的に変換する必要があります。明示的な変換と暗黙的な変換の詳細については、「データ型の変換 (データベース エンジン)」を参照してください。

結合を使用するクエリは、ほとんどの場合サブクエリ、つまりクエリ内で入れ子になった別のクエリを使用して書き換えることができます。またほとんどのサブクエリは結合として書き換えることができます。サブクエリの詳細については、「サブクエリの基礎」を参照してください。

注意

ntext 列、text 列、または image 列を使用してテーブルを直接結合することはできません。ただし、SUBSTRING を使用すれば、ntext 列、text 列、または image 列でテーブルを間接的に結合できます。たとえば、SELECT * FROM t1 JOIN t2 ON SUBSTRING(t1.textcolumn, 1, 20)=SUBSTRING(t2.textcolumn, 1, 20) は t1 テーブルと t2 テーブルの各テキスト列の先頭の 20 文字について 2 つのテーブル内部結合を実行します。WHERE 句を使用して列の長さを比較して、2 つのテーブルの ntext 列または text 列を比較することもできます。例: WHERE DATALENGTH(p1.pr_info) = DATALENGTH(p2.pr_info)。