サブクエリ(SQL Server)

  • 2018年2月18日
  • 読むのに21分
    • W
    • M
    • T
    • M
    • j
    • +3

適用対象: SQL Server(サポートされているすべてのバージョン) AzureSQLデータベース AzureSQLマネージドインスタンス Azure Synapse Analytics 並列データウェアハウス

サブクエリは、SELECTINSERTUPDATEDELETEステートメント、または別のサブクエリ内。サブクエリは、式が許可されている場所であればどこでも使用できます。この例では、サブクエリはSELECTステートメントでMaxUnitPriceという名前の列式として使用されます。

サブクエリの基本

サブクエリも内部クエリまたは内部選択と呼ばれ、サブクエリを含むステートメントは外部クエリまたは外部選択とも呼ばれます。

サブクエリを含む多くのTransact-SQLステートメントは、代わりに結合として定式化できます。その他の質問は、サブクエリでのみ提起できます。 Transact-SQLでは、通常、サブクエリを含むステートメントと、含まない意味的に同等のバージョンとの間にパフォーマンスの違いはありません。ただし、存在を確認する必要がある場合は、結合によってパフォーマンスが向上します。それ以外の場合は、ネストされたクエリを外部クエリの結果ごとに処理して、重複を確実に排除する必要があります。このような場合、結合アプローチの方が良い結果が得られます。以下は、同じ結果セットを返すサブクエリSELECTと結合SELECTの両方を示す例です。

外部SELECTステートメントにネストされたサブクエリには、次のコンポーネントがあります。

  • 通常のSELECTクエリ通常の選択リストコンポーネントを含みます。
  • 1つ以上のテーブル名またはビュー名を含む通常のFROM句。
  • オプションのWHERE句。
  • オプションのGROUP BY句。
  • オプションのHAVING句。

サブクエリのSELECTクエリは常に括弧で囲まれています。 COMPUTEまたはFOR BROWSE句を含めることはできません。また、ORDER BY句のみを含めることができます。 TOP句も指定されます。

サブクエリは、外部のWHEREまたはHAVING句内にネストできます。 SELECTINSERTUPDATE、またはDELETEステートメント、または別のサブクエリ内。最大32レベルのネストが可能ですが、制限は使用可能なメモリとクエリ内の他の式の複雑さによって異なります。個々のクエリは、最大32レベルのネストをサポートしない場合があります。サブクエリは、単一の値を返す場合、式を使用できる場所であればどこにでも表示できます。

テーブルがサブクエリにのみ表示され、外部クエリには表示されない場合、そのテーブルの列をに含めることはできません。出力(外部クエリの選択リスト)。

サブクエリを含むステートメントは、通常、次のいずれかの形式を取ります。

  • WHERE式IN(サブクエリ)
  • WHERE式comparation_operator(サブクエリ)
  • WHERE EXISTS(サブクエリ)

一部のTransact-SQLステートメントでは、サブクエリを独立したものとして評価できます。クエリ。概念的には、サブクエリの結果は外部クエリに置き換えられます(ただし、これは必ずしもSQL Serverがサブクエリを使用してTransact-SQLステートメントを実際に処理する方法ではありません)。

サブクエリには、3つの基本的なタイプがあります。

  • INで導入されたリスト、または比較演算子がANYまたはALL
  • 変更されていない比較演算子で導入され、単一の値を返す必要があります。

サブクエリルール

サブクエリには、次の制限があります。

  • 比較演算子で導入されたサブクエリの選択リストには、式または列名を1つだけ含めることができます(ただし、EXISTSINSELECT *またはリスト)。
  • 外部クエリのWHERE句に列名が含まれている場合は、サブクエリ選択リストの列と結合互換である必要があります。
  • ntext、text、およびimageデータ型は、サブクエリの選択リストでは使用できません。
  • 単一の値を返す必要があるため、変更されていない比較演算子(1つキーワードANYまたはALLが後に続かない場合)GROUP BYおよびHAVING句を含めることはできません。
  • DISTINCTキーワードは、GROUPBYを含むサブクエリでは使用できません。
  • COMPUTEおよびINTO句は指定できません。
  • ORDER BYは、TOPも指定されている場合にのみ指定できます。
  • サブクエリを使用して作成されたビューは更新できません。
  • EXISTSで導入されたサブクエリの選択リストには、慣例によりアスタリスク( *)単一の列名の代わりに。 EXISTSで導入されたサブクエリは存在を作成するため、EXISTSで導入されたサブクエリのルールは標準の選択リストのルールと同じです。テストして、データの代わりにTRUEまたはFALSEを返します。

サブクエリの修飾列名

次の例では、句は、外部クエリのFROM句(Sales.Store)のテーブル名によって暗黙的に修飾されます。サブクエリの選択リストでのCustomerIDへの参照は、サブクエリFROM句、つまりSales.Customerテーブルによって修飾されます。

原則として、ステートメントの列名は、同じレベルのFROM句で参照されるテーブルによって暗黙的に修飾されます。サブクエリのFROM句で参照されているテーブルに列が存在しない場合、その列はFROM外部クエリの句。

これらの暗黙の仮定を指定した場合のクエリは次のようになります。

間違いはありません。テーブル名を明示的に記述し、テーブル名に関する暗黙の仮定を明示的な修飾でオーバーライドすることは常に可能です。

重要

列がサブクエリで参照されている場合サブクエリのFROM句によって参照されるテーブルには存在しませんが、外部クエリのFROMによって参照されるテーブルには存在します。句を指定すると、クエリはエラーなしで実行されます。 SQL Serverは、サブクエリの列を外部クエリのテーブル名で暗黙的に修飾します。

複数レベルのネスト

サブクエリ自体に、1つ以上のサブクエリを含めることができます。ステートメントには任意の数のサブクエリをネストできます。

次のクエリは、営業担当者でもある従業員の名前を検索します。

これが結果セットです。

最も内側のクエリは営業担当者IDを返します。次に高いレベルのクエリは、これらの営業担当者IDで評価され、従業員の連絡先ID番号を返します。最後に、外部クエリは連絡先IDを使用して従業員の名前を検索します。

このクエリを結合として表現することもできます:

多くのクエリは、サブクエリを1回実行し、結果の1つまたは複数の値を外部クエリのWHERE句に代入することで評価できます。相関サブクエリ(繰り返しサブクエリとも呼ばれます)を含むクエリでは、サブクエリはその値を外部クエリに依存します。これは、サブクエリが、外部クエリによって選択される可能性のある行ごとに1回ずつ、繰り返し実行されることを意味します。このクエリは、SalesPersonテーブルのボーナスが5000である各従業員の姓名のインスタンスを1つ取得します。従業員識別番号は、EmployeeテーブルとSalesPersonテーブルで一致します。

結果セットは次のとおりです。

このステートメントの前のサブクエリは、外部クエリとは独立して評価することはできません。Employee.BusinessEntityIDの値が必要ですが、SQL ServerがEmployeeのさまざまな行を調べると、この値は変化します。
これがまさにこの方法です。クエリが評価されます。SQLServerは、各行の値を内部クエリに代入することにより、Employeeテーブルの各行を結果に含めると見なします。たとえば、SQLServerが最初に行を調べてSyed Abbas、変数Employee.BusinessEntityIDは値285を取り、SQLServerがこれを置き換えます

結果は0です(Syed Abbasは、ボーナスを受け取っていません。営業担当者ではない)、したがって、外部クエリは次のように評価されます。

これはfalseであるため、Syed Abbasは結果に含まれません。

Write a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です