테이블 반환 함수로 테이블을 조인하는 방법은 무엇입니까?


53

사용자 정의 함수가 있습니다.

create function ut_FooFunc(@fooID bigint, @anotherParam tinyint)
returns @tbl Table (Field1 int, Field2 varchar(100))
as
begin
  -- blah blah
end

이제 다른 테이블에서 이것을 조인하고 싶습니다.

select f.ID, f.Desc, u.Field1, u.Field2
from Foo f 
join ut_FooFunc(f.ID, 1) u -- doesn't work
where f.SomeCriterion = 1

즉, 1 인 모든 Foo레코드에 SomeCriterion대해 Foo IDDesc의 값과 함께 Field1및 의 입력에 대해 Field2반환되는 및를 보고 싶습니다 .ut_FooFuncFoo.ID

이를 수행하는 구문은 무엇입니까?

답변:


84

CROSS APPLY가입 할 필요가 없습니다.

조인에 관련된 테이블 식의 정의는 안정적이어야합니다. 즉, 테이블 표현식이 다른 테이블의 행 값에 따라 다른 것을 의미하도록 상관 될 수 없습니다.

select f.ID, f.Desc, u.Field1, u.Field2
from Foo f 
Cross apply ut_FooFunc(f.ID, 1) u
where f.SomeCriterion = ...

0

스레드가 오래되었음을 알고 동일한 질문을 받았으며 테스트를 수행했으며 그 결과는 다음과 같습니다.

TestFunction이 독립적으로 실행될 경우 105를 반환하는 동안 FacCurrencyRate = 14264로 기록됩니다.

    SELECT F.*, x.CurrencyKey, x.CurrencyName
    FROM ( 
           SELECT CurrencyKey, CurrencyName FROM dbo.TestFunction()
        ) x
    INNER JOIN [dbo].[FactCurrencyRate] F ON x.CurrencyKey = f.CurrencyKey;

실행 시간은 ...

    (14264 rows affected)
    Table 'FactCurrencyRate'. Scan count 1, logical reads 75, physical reads 1, read-ahead reads 73, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'DimCurrency'. Scan count 1, logical reads 2, physical reads 1, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 31 ms,  elapsed time = 749 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

제안 된 답변을 다음과 같이 사용하면 ...

select F.*, x.CurrencyKey, x.CurrencyName from [dbo].[FactCurrencyRate] F
cross apply dbo.TestFunction() x

실행 시간과 결과 개수는 ...

(1497720 rows affected)
Table 'FactCurrencyRate'. Scan count 1, logical reads 75, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 38110, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'DimCurrency'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 2106 ms,  elapsed time = 43242 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

여기서 볼 수있는 것은 내부 쿼리가보다 정확한 결과 집합을 제공하고 실행 시간이 훨씬 효율적이라는 것입니다. 더 나은 접근 방법으로 저를 수정하십시오!


1
교차 적용은 각 외부 행에 적용되므로 (행 단위로), 특히 큰 데이터 세트에서 속도가 훨씬 느려집니다. TVF와 일치하는 결과 만 원하기 때문에이를 되 돌리면 실행 시간 (아무 것도없는 호출 없음)과 반환되는 행 수를 크게 줄일 수 있지만 두 명령문은 두 번째와 동일하지 않습니다. 정확성이가는 한 비즈니스 요구 사항에 따라 다릅니다
Jonathan Fite

그래, 난 동의. 그러나 테이블 사이에 일대 다 관계가 있다고 가정 한 초기 질문에 비추어 코드를 작성했습니다. 둘째, 인터뷰에서 질문을 받았습니다. 감사합니다
user3104116
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.