如何用表值函数联接表?


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

换句话说,对于所有Foo记录,其中SomeCriterion均为1,我想查看Foo IDDesc以及输入所返回的Field1和的值。Field2ut_FooFuncFoo.ID

这样做的语法是什么?

Answers:


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

我知道线程很旧,有人问我同样的问题,我做了一个测试,结果如下...

以FacCurrencyRate = 14264记录,而TestFunction如果独立执行则返回105。

    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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.