수색…


CROSS APPLY 및 OUTER APPLY 기본 사항

테이블 값 함수가 올바른 식에서 작동 할 때 적용이 사용됩니다.

부서에 대한 정보를 보유하는 부서 테이블을 작성하십시오. 그런 다음 직원에 대한 정보가 들어있는 직원 테이블을 만듭니다. 각 직원은 부서에 속하므로 Employee 테이블에는 부서 테이블과 참조 무결성이 있습니다.

첫 번째 쿼리는 부서 테이블에서 데이터를 선택하고 CROSS APPLY를 사용하여 부서 테이블의 각 레코드에 대한 Employee 테이블을 평가합니다. 두 번째 쿼리는 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의 첫 번째 쿼리는 부서 테이블의 데이터를 선택하고 OUTER APPLY를 사용하여 부서 테이블의 각 레코드에 대한 Employee 테이블을 평가합니다. Employee 테이블에 일치하는 행이없는 행의 경우 행 5와 6에서 볼 수 있듯이 해당 행에는 NULL 값이 들어 있습니다. 두 번째 쿼리는 부서 테이블과 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

위의 두 쿼리가 동일한 정보를 반환하더라도 실행 계획은 조금 다릅니다. 그러나 비용은 현저하게 차이가 없을 것입니다.

이제 APPLY 연산자가 실제로 필요한 위치를 확인해야합니다. Script # 3에서 DepartmentID를 매개 변수로 받아들이는 테이블 반환 함수를 만들고이 부서에 속한 모든 직원을 반환합니다. 다음 쿼리는 Department 테이블에서 데이터를 선택하고 CROSS APPLY를 사용하여 생성 한 함수로 결합합니다. 외부 테이블 표현식 (이 경우에는 부서 테이블)에서 각 행에 대한 DepartmentID를 전달하고 상관 된 부속 조회와 유사한 각 행의 기능을 평가합니다. 다음 u 리는 CROSS APPLY 대신 OUTER APPLY를 사용 하 G로 상관 된 데이터 만 리턴 한 CROSS APPLY와는 달리 OUTER APPLY는 상관되지 않은 데이터도 리턴하여 누락 된 C 럼에 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