【问题标题】:Why can't one join with a table returned from a table valued function?为什么不能与从表值函数返回的表连接?
【发布时间】:2016-06-15 00:23:28
【问题描述】:

具有表值函数 (TVF) 的内连接等效于使用 CROSS APPLY(一个带有 TVF 的 cannot 内连接)。

我想知道为什么 SQL Server 不允许使用 TVF 的返回值连接。具体来说,在 TVF 上执行 CROSS APPLY 与使用临时表进行内部连接有何不同? SQL Server 定义 TVF 的返回表和临时表的方式有区别吗?

【问题讨论】:

  • 通过内部连接,两个表始终保持稳定。使用apply,右侧表格表达式的内容可以针对左侧的每一行进行更改。
  • 如果我们有一个简短的代码示例来说明您正在尝试做什么,我们可以编写一个更好的答案。
  • @MartinSmith 这个答案很有道理。

标签: sql-server


【解决方案1】:

如何在 TVF 上进行 CROSS APPLY 与内部连接不同 临时表?

可以加入 TVF,但您不能在 TVF 调用中使用加入表中的列:

DECLARE @directions VARCHAR(MAX) = 'N, S, W, E' 

SELECT  a.StreetName, s.Value
FROM dbo.Address a 
JOIN dbo.SplitByToken(@directions, ',') s ON a.Direction = s.Value

这里的表值函数基于由标记分隔的字符串列表创建表。这个查询不会有问题,因为表函数的结果是已知的,并且不会根据连接表的结果而改变。它运行一次,结果表连接到Address

当 TVF 与连接表中的列一起使用时,必须使用 cross apply 而不是 join

SELECT  a.ZIP, g.Long, g.Lat
FROM dbo.Address a 
CROSS APPLY dbo.GeoLocation(a.ZIP) g

这里的Geo Location是根据我们计算时使用的表计算出来的,需要Address表的每一行调用一次函数。

【讨论】:

    【解决方案2】:

    考虑以下几点:

    SELECT *
    FROM tblFoo
    INNER JOIN (fnGetTable(tblFoo.someValue)
    

    fnGetTabletblFoo.someValue每个 值返回一个新表。因此,您不是加入一张桌子,而是加入许多桌子。

    我认为最终这与临时表和数据库表是常量对象有关。表值函数不一定每次都返回相同的表对象。

    【讨论】:

      猜你喜欢
      • 2019-01-08
      • 2017-11-23
      • 1970-01-01
      • 1970-01-01
      • 2015-07-07
      • 2011-04-13
      • 2020-04-28
      • 1970-01-01
      • 2019-09-13
      相关资源
      最近更新 更多