내부 조인에 언제 교차 적용을 사용해야합니까?


925

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

cross apply파티셔닝하는 경우 대용량 데이터 세트를 선택할 때 더 효율적일 수있는 ( 인터넷의 게시물을 통해) 읽었습니다 . (페이징이 떠오른다)

또한 CROSS APPLYUDF가 올바른 테이블로 필요하지 않다는 것을 알고 있습니다.

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

누구든지 잘 작동 CROSS APPLY하는 경우에 변화 를 가져올 때 좋은 예를 줄 수 있습니까 INNER 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

50
나는 이것이 나에게도 PICKIER라는 것을 알고 있지만 '실적'은 가장 분명한 단어입니다. 효율성과는 관련이 없습니다.
Rire1979

2
SQL xquery에 매우 유용합니다. 이것을 확인 하십시오 .
ARZ

3
"내부 루프 조인"을 사용하는 것은 교차 적용에 매우 가깝습니다. 어떤 조인 힌트가 동등한 지에 대한 자세한 예제를 원합니다. 조인이라고하면 내부 / 루프 / 병합 또는 "기타"가 발생하여 다른 조인과 다시 정렬 될 수 있습니다.
crokusek 2016 년

3
조인이 많은 행을 만들지 만 한 번에 하나의 행 조인 만 평가하면됩니다. 1 억 개가 넘는 행이있는 테이블에서 자체 조인이 필요하고 메모리가 충분하지 않은 경우가있었습니다. 그래서 메모리 풋 프린트를 낮추기 위해 커서로갔습니다. 커서에서 나는 여전히 관리되는 메모리 풋 프린트로 크로스 적용하고 커서보다 1/3 빠릅니다.
paparazzo

10
CROSS APPLY집합이 다른 JOIN연산자 에 의존하도록 허용하는 명백한 사용법이 있지만 비용이 들지 않습니다. 왼쪽 집합 의 각 멤버에서 작동하는 함수처럼 작동 하므로 SQL Server 용어로 항상 Loop Join집합을 결합하는 가장 좋은 방법은 아닙니다. 따라서 APPLY필요할 때 사용 하지만 과도하게 사용하지 마십시오 JOIN.
Gerardo Lima

답변:


667

INNER JOIN도 잘 작동하는 경우에 CROSS APPLY가 변화를 가져올 때 누구에게나 좋은 예를들 수 있습니까?

자세한 성능 비교는 내 블로그의 기사를 참조하십시오.

CROSS APPLY간단한 JOIN조건 이없는 것들에 더 잘 작동 합니다.

다음 3에서 t2각 레코드의 마지막 레코드를 선택합니다 t1.

SELECT  t1.*, t2o.*
FROM    t1
CROSS APPLY
        (
        SELECT  TOP 3 *
        FROM    t2
        WHERE   t2.t1_id = t1.id
        ORDER BY
                t2.rank DESC
        ) t2o

INNER JOIN조건 으로는 쉽게 공식화 할 수 없습니다 .

CTE의 및 창 기능 을 사용하여 이와 같은 작업을 수행 할 수 있습니다.

WITH    t2o AS
        (
        SELECT  t2.*, ROW_NUMBER() OVER (PARTITION BY t1_id ORDER BY rank) AS rn
        FROM    t2
        )
SELECT  t1.*, t2o.*
FROM    t1
INNER JOIN
        t2o
ON      t2o.t1_id = t1.id
        AND t2o.rn <= 3

하지만 읽기가 어렵고 효율성이 떨어집니다.

최신 정보:

방금 확인했습니다.

masteron에 대한 20,000,000레코드 에 대한 테이블입니다 .PRIMARY KEYid

이 쿼리는

WITH    q AS
        (
        SELECT  *, ROW_NUMBER() OVER (ORDER BY id) AS rn
        FROM    master
        ),
        t AS 
        (
        SELECT  1 AS id
        UNION ALL
        SELECT  2
        )
SELECT  *
FROM    t
JOIN    q
ON      q.rn <= t.id

거의 30몇 초 동안 실행 되지만이 중 하나는 다음과 같습니다.

WITH    t AS 
        (
        SELECT  1 AS id
        UNION ALL
        SELECT  2
        )
SELECT  *
FROM    t
CROSS APPLY
        (
        SELECT  TOP (t.id) m.*
        FROM    master m
        ORDER BY
                id
        ) q

인스턴트입니다.


2
Ariel의 링크 끝을 참조하십시오. row_number () 쿼리는 훌륭하고 조인이 필요하지 않습니다. 따라서이 상황에 교차 적용을 사용해야한다고 생각하지 않습니다 (t1.id로 파티션 3을 선택하십시오).
Jeff Meatball Yang

375
이것이 가장 인기있는 답변이지만 실제 질문 "CROSS APPLY를 사용하는 주요 목적은 무엇입니까?" 주요 목적은 매개 변수가있는 테이블 함수를 행당 한 번 실행 한 다음 결과에 결합 할 수 있도록하는 것입니다.
MikeKulls

5
@ 마이크 : 당신은 어떻게 호출 할 TVFINNER JOIN?
Quassnoi

15
예 @MikeKulls하지만, 영업 이익은 사용하는 주요 목적을 요청하지 않았다 CROSS APPLY, 그는 그것을 통해 선택할 때 요구 INNER JOIN즉 잘 작동 할 때.
ErikE

8
그것은 가치가이라는 것을 언급 될 수있는 lateral join표준 (ANSI) SQL
a_horse_with_no_name

198

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

하나:

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

이것은 합법적입니다.

편집 : 또는 대안으로 더 짧은 구문 : (by 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 +에는 측면 파생 테이블이 있으며 Postgresql (9.3+)에는 비슷한 효과에 사용할 수있는 측면 서브 쿼리 가 있습니다.


11
이것이 우리가 왜 교차 신청을했는지에 대한 추론이라고 생각합니다. 아래 링크를 확인하면 MS가 교차 적용에 대해 가장 먼저 말하는 것입니다. 다른 용도로 사용될 수도 있지만 이것이 이것이 도입 된 이유라고 생각합니다. 그것 없이는 많은 상황에서 테이블 함수를 사용할 수 없습니다. technet.microsoft.com/en-us/library/ms175156.aspx
MikeKulls

cross apply는 또한 필요한 모듈성을 유지하면서 인라인 테이블 함수와 결합 될 때 훌륭한 실행 계획을 생성합니다.
nurettin

14
SELECT안에 필요 하지 않습니다 CROSS APPLY. 시도하십시오 CROSS APPLY dbo.myTableFun(O.name) F.
ErikE

1
@ErikE 확실히, 덜 유연한 구문을 사용하여 교차 적용 할 수 있습니다. 계산에 열을 계산하기가 어렵게하기 위해 때로는 사용할 수있는보다 일반적인 버전을 보여주었습니다.
nurettin

2
테이블 함수 매개 변수가 외부 선택의 다른 테이블 열 (일명 외부 참조)에 의존하는 경우 @Bolu 내부 조인이 작동하지 않습니다. 테이블 함수 매개 변수가 리터럴 또는 변수 인 경우 작동합니다. 두 경우 모두 교차 적용이 적용됩니다.
nurettin

175

두 개의 테이블이 있다고 가정하십시오.

마스터 테이블

x------x--------------------x
| Id   |        Name        |
x------x--------------------x
|  1   |          A         |
|  2   |          B         |
|  3   |          C         |
x------x--------------------x

세부 사항 테이블

x------x--------------------x-------x
| Id   |      PERIOD        |   QTY |
x------x--------------------x-------x
|  1   |   2014-01-13       |   10  |
|  1   |   2014-01-11       |   15  |
|  1   |   2014-01-12       |   20  |
|  2   |   2014-01-06       |   30  |
|  2   |   2014-01-08       |   40  |
x------x--------------------x-------x

우리는 교체 할 필요가 많은 상황이있다 INNER JOIN와 함께 CROSS APPLY.

1. TOP n결과에 따라 두 테이블을 조인

우리가 선택해야 할 경우 고려 IdName에서 Master각 마지막 두 날짜 Id에서 Details table.

SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
INNER JOIN
(
    SELECT TOP 2 ID, PERIOD,QTY 
    FROM DETAILS D      
    ORDER BY CAST(PERIOD AS DATE)DESC
)D
ON M.ID=D.ID

위 쿼리는 다음과 같은 결과를 생성합니다.

x------x---------x--------------x-------x
|  Id  |   Name  |   PERIOD     |  QTY  |
x------x---------x--------------x-------x
|   1  |   A     | 2014-01-13   |  10   |
|   1  |   A     | 2014-01-12   |  20   |
x------x---------x--------------x-------x

마지막 두 날짜의 마지막 두 날짜에 대한 결과를 생성 Id한 다음의 외부 쿼리에서만 이러한 레코드를 조인했습니다 Id. 이것은 Ids1과 2를 모두 반환해야 하지만 1에는 마지막 두 날짜가 있기 때문에 1 만 반환했습니다. 이를 위해서는을 사용해야 CROSS APPLY합니다.

SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
CROSS APPLY
(
    SELECT TOP 2 ID, PERIOD,QTY 
    FROM DETAILS D  
    WHERE M.ID=D.ID
    ORDER BY CAST(PERIOD AS DATE)DESC
)D

다음 결과를 형성합니다.

x------x---------x--------------x-------x
|  Id  |   Name  |   PERIOD     |  QTY  |
x------x---------x--------------x-------x
|   1  |   A     | 2014-01-13   |  10   |
|   1  |   A     | 2014-01-12   |  20   |
|   2  |   B     | 2014-01-08   |  40   |
|   2  |   B     | 2014-01-06   |  30   |
x------x---------x--------------x-------x

작동 방식은 다음과 같습니다. 내부 쿼리 CROSS APPLY는 외부 테이블을 참조 INNER JOIN할 수 있습니다.이 작업을 수행 할 수 없습니다 (컴파일 오류가 발생 함). 마지막 두 날짜를 찾을 때, 내부에서 수행되는 접합 CROSS APPLY, 즉 WHERE M.ID=D.ID.

2. INNER JOIN기능을 사용하여 기능이 필요한 경우 .

CROSS APPLYtable과 a INNER JOIN에서 결과를 얻어야 할 때를 대신하여 사용할 수 있습니다 .Masterfunction

SELECT M.ID,M.NAME,C.PERIOD,C.QTY
FROM MASTER M
CROSS APPLY dbo.FnGetQty(M.ID) C

그리고 여기 기능이 있습니다

CREATE FUNCTION FnGetQty 
(   
    @Id INT 
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT ID,PERIOD,QTY 
    FROM DETAILS
    WHERE ID=@Id
)

다음 결과를 생성했습니다

x------x---------x--------------x-------x
|  Id  |   Name  |   PERIOD     |  QTY  |
x------x---------x--------------x-------x
|   1  |   A     | 2014-01-13   |  10   |
|   1  |   A     | 2014-01-11   |  15   |
|   1  |   A     | 2014-01-12   |  20   |
|   2  |   B     | 2014-01-06   |  30   |
|   2  |   B     | 2014-01-08   |  40   |
x------x---------x--------------x-------x

크로스 적용의 추가 이점

APPLY의 대체품으로 사용할 수 있습니다 UNPIVOT. 하나 CROSS APPLY또는 OUTER APPLY교환 할 수있는, 여기에 사용할 수 있습니다.

아래 표 ( MYTABLE) 가 있다고 가정하십시오 .

x------x-------------x--------------x
|  Id  |   FROMDATE  |   TODATE     |
x------x-------------x--------------x
|   1  |  2014-01-11 | 2014-01-13   | 
|   1  |  2014-02-23 | 2014-02-27   | 
|   2  |  2014-05-06 | 2014-05-30   | 
|   3  |     NULL    |    NULL      |
x------x-------------x--------------x

검색어는 다음과 같습니다.

SELECT DISTINCT ID,DATES
FROM MYTABLE 
CROSS APPLY(VALUES (FROMDATE),(TODATE))
COLUMNNAMES(DATES)

결과를 가져옵니다

  x------x-------------x
  | Id   |    DATES    |
  x------x-------------x
  |  1   |  2014-01-11 |
  |  1   |  2014-01-13 |
  |  1   |  2014-02-23 |
  |  1   |  2014-02-27 |
  |  2   |  2014-05-06 |
  |  2   |  2014-05-30 | 
  |  3   |    NULL     | 
  x------x-------------x

4
2 대 4 레코드의 훌륭한 예이며 이것이 필요한 상황을 이해하는 데 도움이되었습니다.
trnelson

13
이 답변은 허용 된 페이지를 선택하는 대신 페이지를 아래로 스크롤하는 것이 실제로 가치가 있음을 증명합니다.
Mostafa Armandi

2
지금까지 APPLY 사용법을 설명하는 가장 좋은 예 ... 많은 게시물을 읽었으며이 설명으로 인해 그림이 물처럼 명확 해집니다. 많은 감사합니다.
AG7

1
ID 1, 2의 경우 4 행 대신 ID 1의 경우 2 행이있는 포인트 1의 경우 대신 왼쪽 조인을 사용하지 않겠습니다.
Joseph Cho

43

CROSS APPLY는 복잡하고 중첩 된 쿼리에서 계산 된 필드로 작업 할 때 특정 간격을 메울 수 있으며 더 간단하고 읽기 쉽습니다.

간단한 예 : DoB가 있고 최종 사용자 애플리케이션에 사용하기 위해 Age, AgeGroup, AgeAtHiring, MinimumRetirementDate 등과 같은 다른 데이터 소스 (예 : 고용)에 의존하는 여러 연령 관련 필드를 제시하려고합니다. (예 : Excel 피벗 테이블).

옵션은 제한적이고 거의 우아하지 않습니다.

  • JOIN 하위 쿼리는 상위 쿼리의 데이터를 기반으로 데이터 집합에 새 값을 도입 할 수 없습니다 (자체로 서 있어야 함).

  • UDF는 깔끔하지만 병렬 작업을 방해하는 경향이 있으므로 느립니다. 그리고 별도의 엔티티가되는 것은 좋은 것 (코드가 적음)이거나 나쁜 것 (코드가있는 곳) 일 수 있습니다.

  • 접합 테이블. 때때로 그들은 작동 할 수 있지만 곧 당신은 많은 UNION과 서브 쿼리에 참여할 것입니다. 큰 혼란.

  • 계산에 기본 쿼리 중간에 얻은 데이터가 필요하지 않다고 가정하면 또 다른 단일 목적 뷰를 작성하십시오.

  • 중개 테이블. 예 ... 일반적으로 작동하며 종종 색인화되고 빠를 수 있으므로 좋은 옵션이지만 UPDATE 문이 병렬이 아니고 수식을 재사용 (결과 재사용)하여 여러 필드를 업데이트하지 않아 성능이 저하 될 수 있습니다. 같은 진술. 때로는 한 번에 한 번만 수행하는 것을 선호하기도합니다.

  • 중첩 쿼리. 예, 언제든지 전체 쿼리에 괄호를 넣고 소스 데이터와 계산 된 필드를 모두 조작 할 수있는 하위 쿼리로 사용할 수 있습니다. 그러나 추악 해지기 전에는 그렇게 많이 할 수 있습니다. 아주 못생긴.

  • 반복 코드. 3 개의 long (CASE ... ELSE ... END) 문 중 가장 큰 값은 무엇입니까? 읽을 수 있습니다!

    • 고객에게 지독한 것을 스스로 계산하도록 지시하십시오.

내가 뭘 놓 쳤니? 아마, 자유롭게 의견을 말하십시오. 그러나 CROSS APPLY는 그러한 상황에서 신의 선물과 같습니다. 당신은 간단 CROSS APPLY (select tbl.value + 1 as someFormula) as crossTbl하고 자비를 추가합니다 ! 이제 새 필드는 소스 데이터에 항상 존재했던 것처럼 실제로 사용할 수 있습니다.

CROSS APPLY를 통해 도입 된 가치는 ...

  • 믹스에 성능, 복잡성 또는 가독성 문제를 추가하지 않고 하나 또는 여러 개의 계산 된 필드를 만드는 데 사용
  • JOIN과 마찬가지로 몇 가지 후속 CROSS APPLY 문이 자신을 참조 할 수 있습니다. CROSS APPLY (select crossTbl.someFormula + 1 as someMoreFormula) as crossTbl2
  • 후속 조인 조건에서 CROSS APPLY에 의해 도입 된 값을 사용할 수 있습니다.
  • 보너스로 테이블 반환 함수 측면이 있습니다.

Dang, 그들이 할 수있는 일은 없습니다!


1
더 자주 언급되지 않은 것에 놀랐 기 때문에 이것은 나에게서 큰 +1입니다. 아마도이 예제를 확장하여 파생 값 체인에서 "절차"계산을 수행하는 방법을 보여줄 수 있습니까? 예 : CROSS APPLY (crossTbl.value * tbl.multiplier를 곱한 것으로 선택) multiTbl-CROSS APPLY (multiTbl.Multiplied / tbl.DerivativeRatio를 파생으로 선택) 파생 된 Tbl-etc ...
mrmillsy

1
CASE..ELSE..END의 대체품으로 Cross Apply를 사용하는 방법에 대한 추가 정보 / 예는?
przemo_li

3
@przemo_li APPLY는이를 참조하기 위해 case 문의 결과를 저장하는 데 사용될 수 있습니다. subquery.intermediateResult> 0 일 때 SELECT CASE 구조 다음과 같은 구조가 될 수 있습니다. someTable OUTER APPLY (CASE ... END ... ELSE를 중간 결과로 선택)에서 "예"ELSE "아니오"END를 하위 쿼리로 선택하십시오.
mtone

14

교차 적용은 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

13

이것은 이미 기술적으로 매우 잘 대답되었지만 그것이 어떻게 매우 유용한 지에 대한 구체적인 예를 보여 드리겠습니다.

Customer 테이블과 Order 테이블이 있다고 가정 해 봅시다. 고객에게 많은 주문이 있습니다.

고객에 대한 세부 정보와 고객이 주문한 최근 주문을 제공하는보기를 만들고 싶습니다. JOINS 만 있으면 자체 조인과 집계가 필요하지만 꽤 좋지는 않습니다. 그러나 Cross Apply를 사용하면 매우 쉽습니다.

SELECT *
FROM Customer
CROSS APPLY (
  SELECT TOP 1 *
  FROM Order
  WHERE Order.CustomerId = Customer.CustomerId
  ORDER BY OrderDate DESC
) T

7

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

하위 쿼리

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

5

나는 가독성이어야한다고 생각합니다.)

CROSS APPLY는 왼쪽 표의 각 행에 적용되는 UDF가 사용되고 있다고 말하는 사람들에게 다소 독특합니다.

물론, 다른 친구가 위에 게시 한 JOIN보다 CROSS APPLY가 더 잘 사용되는 다른 제한이 있습니다.


4

다음은 JOINS에 대한 성능 차이 및 사용법과 함께 모든 내용을 설명하는 기사입니다.

JOINS를 통한 SQL Server CROSS APPLY 및 OUTER APPLY

이 기사에서 제안한 것처럼 일반 조인 작업 (INNER AND CROSS)에 대해서는 성능 차이가 없습니다.

여기에 이미지 설명을 입력하십시오

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

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 "를 바인딩 할 수 없습니다." 오류가 발생 합니다. 여기서 각 행을 읽을 때 값이 함수에 전달됩니다. 나에게 시원하게 들린다. :)


3

글쎄, 이것이 Cross Apply와 Inner Join을 사용해야하는 이유인지 확실하지 않지만 Cross Apply를 사용하여 포럼 게시물 에서이 쿼리에 대한 답변을 얻었으므로 Inner Join을 사용하는 동등한 방법이 있는지 확실하지 않습니다.

Create PROCEDURE [dbo].[Message_FindHighestMatches]

-- Declare the Topical Neighborhood
@TopicalNeighborhood nchar(255)

시작으로

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON

Create table  #temp
(
    MessageID         int,
    Subjects          nchar(255),
    SubjectsCount    int
)

Insert into #temp Select MessageID, Subjects, SubjectsCount From Message

Select Top 20 MessageID, Subjects, SubjectsCount,
    (t.cnt * 100)/t3.inputvalues as MatchPercentage

From #temp 

cross apply (select count(*) as cnt from dbo.Split(Subjects,',') as t1
             join dbo.Split(@TopicalNeighborhood,',') as t2
             on t1.value = t2.value) as t
cross apply (select count(*) as inputValues from dbo.Split(@TopicalNeighborhood,',')) as t3

Order By MatchPercentage desc

drop table #temp

종료


3

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

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

APPLY 연산자의 상관 관계에 대해 말하면 오른쪽에 다음을 넣을 수 있습니다.

  • 파생 테이블-별명을 가진 상관 서브 쿼리
  • 테이블 값 함수-매개 변수가있는 개념적보기. 매개 변수가 왼쪽을 참조 할 수 있음

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


2

이것은 아마도 오래된 질문이지만 여전히 논리 재사용을 단순화하고 결과에 대한 "체인"메커니즘을 제공하는 CROSS APPLY의 힘을 여전히 좋아합니다.

CROSS APPLY를 사용하여 데이터 세트에서 복잡한 작업을 수행하여 복잡한 작업을 수행하는 방법에 대한 간단한 예를 보여주는 SQL Fiddle을 아래에 제공했습니다. 여기에서 더 복잡한 계산을 추정하는 것은 어렵지 않습니다.

http://sqlfiddle.com/#!3/23862/2


1

CROSS APPLY를 사용하는 대부분의 쿼리는 INNER JOIN을 사용하여 다시 작성할 수 있지만 CROSS APPLY는 조인이 발생하기 전에 조인 된 집합을 제한 할 수 있으므로 실행 계획과 성능이 향상 될 수 있습니다.

여기 에서 도난

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.