[sql] Cross Join Apply to Inner Join은 언제 사용해야합니까?



5 Answers

cross apply 때때로 당신이 inner join 할 수없는 일들을 할 수있게 해줍니다.

예 (구문 오류) :

select F.* from sys.objects O  
inner join dbo.myTableFun(O.name) F   
on F.schema_id= O.schema_id

inner join 과 함 2 사용될 때 테이블 함수는 변수 또는 상수 를 매개 변수로 취할 수 있기 때 문에 구문 오류 입니다. (즉, 테이블 함수 매개 변수는 다른 테이블의 열에 종속 될 수 없습니다.)

하나:

select F.* from sys.objects O  
cross apply ( select * from dbo.myTableFun(O.name) ) F  
where F.schema_id= O.schema_id

이것은 합법적입니다.

편집 : 또는 짧은 구문 : (ErikE)

select F.* from sys.objects O  
cross apply dbo.myTableFun(O.name) F
where F.schema_id= O.schema_id

편집하다:

참고 : Informix 12.10 xC2 +에는 Lateral Derived Tables가 있고 Postgresql (9.3+)에는 비슷한 효과를 낼 수있는 Lateral Subqueries 가 있습니다.

Question

CROSS APPLY 사용의 주 목적은 무엇입니까?

필자는 파티션 된 경우 큰 데이터 세트를 선택할 때 cross apply 이 더 효율적일 수 있다는 것을 (막연하게 인터넷상의 게시물을 통해) 읽었습니다. (페이징이 떠오른다)

또한 CROSS APPLY 는 UDF를 오른쪽 테이블로 필요로하지 않는다는 것을 알고 있습니다.

대부분의 INNER JOIN 쿼리 (일대 다 관계)에서 CROSS APPLY 를 사용하도록 다시 작성할 수 있지만 항상 동일한 실행 계획을 제공합니다.

누구도 CROSS APPLYINNER JOIN 이 잘 작동하는 경우에 차이를 만드는 좋은 예를 들어 줄 수 있습니까?

편집하다:

실행 계획이 정확히 동일한 간단한 예제가 있습니다. (서로 다른 위치와 cross apply 이 더 효율적 /보다 효율적인 위치를 보여주십시오)

create table Company (
    companyId int identity(1,1)
,   companyName varchar(100)
,   zipcode varchar(10) 
,   constraint PK_Company primary key (companyId)
)
GO

create table Person (
    personId int identity(1,1)
,   personName varchar(100)
,   companyId int
,   constraint FK_Person_CompanyId foreign key (companyId) references dbo.Company(companyId)
,   constraint PK_Person primary key (personId)
)
GO

insert Company
select 'ABC Company', '19808' union
select 'XYZ Company', '08534' union
select '123 Company', '10016'


insert Person
select 'Alan', 1 union
select 'Bobby', 1 union
select 'Chris', 1 union
select 'Xavier', 2 union
select 'Yoshi', 2 union
select 'Zambrano', 2 union
select 'Player 1', 3 union
select 'Player 2', 3 union
select 'Player 3', 3 


/* using CROSS APPLY */
select *
from Person p
cross apply (
    select *
    from Company c
    where p.companyid = c.companyId
) Czip

/* the equivalent query using INNER JOIN */
select *
from Person p
inner join Company c on p.companyid = c.companyId



JOINS를 능가하는 성능 차이와 사용법을 모두 설명하는 기사가 있습니다.

SQL Server Cross는 JOINS에 적용됩니다.

이 기사에서 제안한 것처럼 일반적인 조인 작업 (내부 및 크로스)에서는 성능 차이가 없습니다.

다음과 같은 쿼리를 수행해야 할 때 사용량 차이가 발생합니다.

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)

즉, 기능과 관련이 있어야합니다. INNER JOIN을 사용하면 "다중 파트 식별자"D.DepartmentID "를 바인딩 할 수 없습니다."라는 오류 메시지가 나타납니다. 여기에서 값은 각 행을 읽을 때 함수에 전달됩니다. 나는 시원하게 들린다. :)




교차 적용은 XML 필드에서도 잘 작동합니다. 다른 필드와 결합하여 노드 값을 선택하려는 경우.

예를 들어, 일부 xml을 포함하는 테이블

<root>
    <subnode1>
       <some_node value="1" />
       <some_node value="2" />
       <some_node value="3" />
       <some_node value="4" />
    </subnode1>
</root>

쿼리 사용하기

SELECT
       id as [xt_id]
      ,xmlfield.value('(/root/@attribute)[1]', 'varchar(50)') root_attribute_value
  ,node_attribute_value = [some_node].value('@value', 'int')
  ,lt.lt_name   
FROM dbo.table_with_xml xt
CROSS APPLY xmlfield.nodes('/root/subnode1/some_node') as g ([some_node])
LEFT OUTER JOIN dbo.lookup_table lt
ON [some_node].value('@value', 'int') = lt.lt_id

결과를 반환합니다.

xt_id root_attribute_value node_attribute_value lt_name
----------------------------------------------------------------------
1     test1            1                    Benefits
1     test1            4                    FINRPTCOMPANY



교차 적용은 하위 쿼리의 열이 필요한 하위 쿼리를 대체하는 데 사용할 수 있습니다.

하위 쿼리

select * from person p where
p.companyId in(select c.companyId from company c where c.companyname like '%yyy%')

여기서는 회사 테이블의 열을 선택할 수 없으므로 교차 적용을 사용합니다.

select P.*,T.CompanyName
from Person p
cross apply (
    select *
    from Company C
    where p.companyid = c.companyId and c.CompanyName like '%yyy%'
) T






APPLY 연산자의 본질은 FROM 절에서 연산자의 왼쪽과 오른쪽 사이의 상관 관계를 허용하는 것입니다.

JOIN과 달리 입력 간의 상관 관계는 허용되지 않습니다.

APPLY 연산자의 상관 관계에 대해 말하면, 오른쪽에 다음과 같이 입력 할 수 있습니다.

  • 파생 테이블 - 별칭이있는 상관 된 하위 쿼리
  • 테이블 값 함수 - 매개 변수가있는 개념적보기. 여기서 매개 변수는 왼쪽을 참조 할 수 있습니다.

둘 다 여러 열과 행을 반환 할 수 있습니다.




Related