サーチ…


CROSS APPLYとOUTER APPLYの基本

右の式でテーブル値関数が使用されているときに適用が使用されます。

部門に関する情報を保持する部門テーブルを作成します。その後、従業員に関する情報を保持するEmployeeテーブルを作成します。各従業員は部門に属しているため、従業員テーブルにはDepartmentテーブルとの参照整合性があります。

最初のクエリは部門テーブルからデータを選択し、CROSS APPLYを使用してDepartmentテーブルの各レコードのEmployeeテーブルを評価します。 2番目のクエリは、DepartmentテーブルをEmployeeテーブルに結合するだけで、すべての一致するレコードが生成されます。

SELECT *
FROM Department D
CROSS APPLY (
    SELECT *
    FROM Employee E
    WHERE E.DepartmentID = D.DepartmentID
) A
GO
SELECT *
FROM Department D
INNER JOIN Employee E
  ON D.DepartmentID = E.DepartmentID

作成した結果を見ると、まったく同じ結果セットになります。 JOINとどのように違うのですか?また、より効率的なクエリを書く上でどのように役立ちますか?

スクリプト#2の最初のクエリは、Departmentテーブルのデータを選択し、OUTER APPLYを使用してDepartmentテーブルの各レコードのEmployeeテーブルを評価します。 Employeeテーブルに一致しない行については、行5と6の場合に見られるように、これらの行にNULL値が含まれます。2番目のクエリは、DepartmentテーブルとEmployeeテーブルの間にLEFT OUTER JOINを使用するだけです。期待どおり、クエリは部門テーブルからすべての行を返します。 Employeeテーブルに一致するものがない行であっても同様です。

SELECT *
FROM Department D
OUTER APPLY (
    SELECT *
    FROM Employee E
    WHERE E.DepartmentID = D.DepartmentID
) A
GO
SELECT *
FROM Department D
LEFT OUTER JOIN Employee E
  ON D.DepartmentID = E.DepartmentID
GO

上記の2つのクエリが同じ情報を返しても、実行計画は少し異なります。しかし、コストはあまり違いはありません。

今、APPLY演算子が本当に必要な場所を確認する時間が来る。 Script#3では、DepartmentIDをパラメータとして受け取り、この部門に属するすべての従業員を返すテーブル値関数を作成しています。次のクエリは、Departmentテーブルからデータを選択し、CROSS APPLYを使用して、作成した関数と結合します。外部テーブル式(ここではDepartmentテーブル)から各行のDepartmentIDを渡し、相関サブクエリに似た各行の関数を評価します。次の照会は、CROSS APPLYの代わりにOUTER APPLYを使用するため、相関データのみを戻したCROSS APPLYとは異なり、OUTER APPLYは無相関のデータも戻し、欠落した列にNULLを入れます。

CREATE FUNCTION dbo.fn_GetAllEmployeeOfADepartment (@DeptID AS int)
RETURNS TABLE
AS
  RETURN
  (
  SELECT
    *
  FROM Employee E
  WHERE E.DepartmentID = @DeptID
  )
GO
SELECT
  *
FROM Department D
CROSS APPLY dbo.fn_GetAllEmployeeOfADepartment(D.DepartmentID)
GO
SELECT
  *
FROM Department D
OUTER APPLY dbo.fn_GetAllEmployeeOfADepartment(D.DepartmentID)
GO

今疑問に思っている方は、上記のクエリの代わりに単純な結合を使用できますか?上記のクエリのCROSS / OUTER APPLYをINNER JOIN / LEFT OUTER JOINに置き換え、ON句(1 = 1)を指定してクエリを実行すると、「マルチパート識別子」が得られます。 D.DepartmentIDは「バインドできませんでした」エラー。 JOINでは、外部クエリの実行コンテキストが関数(または派生テーブル)の実行コンテキストと異なるため、外部クエリの値/変数をパラメータとして関数にバインドすることができないためです。したがって、そのような照会にはAPPLY演算子が必要です。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow