2013-08-08 8 views
3

테이블 연산자 APPLY을 이해하려고합니다.이 APPLY를 사용하는 경우테이블 연산자를 사용하는 경우

CREATE TABLE #y (Name char(8), hoursWorked int); 
GO 
INSERT INTO #y VALUES ('jim',4); 
INSERT INTO #y VALUES ('michael',40); 
INSERT INTO #y VALUES ('raj',1000); 
INSERT INTO #y VALUES ('jason',7); 
INSERT INTO #y VALUES ('tim',50); 
GO 

CREATE TABLE #x (Name char(8),game char(8), NumBets int); 
GO 
INSERT INTO #x VALUES ('jim','chess',4); 
INSERT INTO #x VALUES ('jim','BG',10); 
INSERT INTO #x VALUES ('jim','draughts',100); 
INSERT INTO #x VALUES ('jim','football',5); 
INSERT INTO #x VALUES ('michael','chess',40); 
INSERT INTO #x VALUES ('michael','BG',7); 
INSERT INTO #x VALUES ('michael','draughts',65); 
INSERT INTO #x VALUES ('michael','football',50); 
INSERT INTO #x VALUES ('raj','chess',400); 
INSERT INTO #x VALUES ('raj','BG',70); 
INSERT INTO #x VALUES ('raj','draughts',650); 
INSERT INTO #x VALUES ('tim','draughts',60000); 
GO 

SELECT y.Name, 
     y.hoursWorked, 
     x.game, 
     x.NumBets 
FROM #y y 
     OUTER APPLY 
      (
      SELECT TOP 2 * 
      FROM #x 
      WHERE Name = y.Name 
      ORDER BY NumBets 
     ) x 
ORDER BY y.Name, 
     x.NumBets DESC; 

내 주요 장애물이 을 이해하는 것입니다 : 여기

은 예입니다.
에 구현 된 standard sql을 사용하면 위와 같은 결과를 얻는 것이 얼마나 어려울 지 궁금합니다.
APPLY 쿼리를 훨씬 더 짧게 또는 더 가독성있게 만드십니까?
APPLY을 사용하는 데 큰 이점이없는 경우 APPLY을 사용하는 이점이있는 명확한 예가 무엇입니까? 모든

답변

3

먼저 - 당신이 매개 변수 값은 조회 테이블에서 가져옵니다 테이블 반환 함수,이 같은 호출 할 수 apply로 :

select 
    t1.col3, -- column from table 
    f1.col1 -- column from function 
from table1 as t1 
    left outer join table2 as t2 on t2.col1 = t1.col1 
    outer apply dbo.function1(t1.col1, t2.col2) as f1 

또는 파쇄 XML 열을

select 
    t1.col3, 
    t.c.value('@value', 'int') as value 
from table1 as t1 
    -- table1.col1 is xml iike <Data @Value="...">...</Data> 
    outer apply t1.col1.nodes('Data') as t(c) 

내 expirience에서 일부를 만들어야 할 때 매우 유용합니다 미리 계산 :

select 
    t1.col3, 
    a1.col1, --calculated value 
    a2.col1 -- another calculated value, first one was used 
from table1 as t1 
    outer apply (select t1.col1 * 5 as col1) as a1 
    outer apply (select a1.col1 - 4 as col1) as a2 

apply를 사용하는 또 다른 예는 작동 피벗 해제 :

select 
    t1.col1, c.name, c.value 
from table1 as t1 
    outer apply (
     select 'col1', t1.col1 union all 
     select 'col2', t1.col2 
    ) as c(name, value) 

마지막으로, 여기에 를 사용하지 않고 SQL 2005의 관점에서 구현 쿼리 적용

;with cte as (
    select 
     y.Name, 
     y.hoursWorked, 
     x.game, 
     x.NumBets, 
     row_number() over(partition by x.Name order by x.NumBets) as row_num 
    from y 
     left outer join x on x.Name = y.Name 
) 
select Name, hoursWorked, game, NumBets 
from cte 
where row_num <= 2 
order by Name, NumBets desc 

참조예

+1

+1 아주 좋은 광범위한 답변 - 아직 완전히 이것을 흡수 할 시간이 없었습니다. – whytheq

+0

나는 'APPLY'가 2005 버전보다 짧다고 생각합니다. 확실하지는 않지만'UNPIVOT' 버전을 사용하면 좋겠지 만 좋은 트릭이지만 UNPIVOT 함수가 SQL Server의 동일한 버전과 함께 제공되는 이유는 그것을 사용하지 않는 이유입니다. 나를 위해, 최고의 응용 프로그램은 TVF와의 상호 작용 및 계산에 대한 적용의 상관 된 사용이 될 것입니다. – whytheq

+0

나는 Apply가 row_number보다 빠를 수 있다고 생각하지만 이것에 대해서는 확신 할 수 없다. 나중에 테스트해야한다. –