テーブル値関数でテーブルを結合する方法は?


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 IDDescField1Field2ut_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で一致する結果のみが必要なため、実行時間(何もしない呼び出しはありません)および返される行数が大幅に削減されます。ただし、2つのステートメントは2番目のステートメントと同等ではありませんは、最初の行よりもはるかに多くの行を返します。正確さに関しては、それはビジネス要件によって異なります
Jonathan Fite

はい私は同意する。ただし、最初の質問に照らしてコードを記述しましたが、テーブル間には1対多の関係があると想定していました。そして、第二に、インタビューで質問を受けました。おかげで
user3104116
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.