我一直在和一位同事一起看 CROSS / OUTER APPLY
,我们正在努力寻找真实生活中使用它们的例子 .
我花了很多时间看When should I use Cross Apply over Inner Join?和Google搜索,但主要(唯一)的例子看起来很奇怪(使用表中的rowcount来确定从另一个表中选择多少行) .
我认为这种情况可能会受益于 OUTER APPLY
:
联系人表(每个联系人包含1条记录)通讯条目表(每个联系人可以包含n个电话,传真,电子邮件)
但是使用子查询,公共表表达式 OUTER JOIN
与 RANK()
和 OUTER APPLY
似乎都表现相同 . 我'm guessing this means the scenario isn'适用于 APPLY
.
请分享一些现实生活中的例子并帮助解释这个功能!
4 回答
在各种情况下,您无法避免
CROSS APPLY
或OUTER APPLY
.考虑你有两张 table .
MASTER TABLE
DETAILS TABLE
在很多情况下我们需要用
CROSS APPLY
替换INNER JOIN
.1. If we want to join 2 tables on TOP n results with INNER JOIN functionality
考虑是否需要从
Master
中选择Id
和Name
,并从Details table
中为每个Id
选择最后两个日期 .以上查询生成以下结果 .
看,它生成最后两个日期的结果,最后两个日期是
Id
,然后仅在Id
的外部查询中加入这些记录,这是错误的 . 为此,我们需要使用CROSS APPLY
.并形成他的结果 .
这是工作 .
CROSS APPLY
中的查询可以引用外部表,其中INNER JOIN
不能执行此操作(抛出编译错误) . 找到最后两个日期时,加入在CROSS APPLY
内完成,即WHERE M.ID=D.ID
.2. When we need INNER JOIN functionality using functions.
当我们需要从
Master
表和function
获得结果时,CROSS APPLY
可以用作INNER JOIN
的替代 .这是功能
产生了以下结果
1. If we want to join 2 tables on TOP n results with LEFT JOIN functionality
考虑我们是否需要从
Master
中选择Id和Name,并从Details
表中为每个Id选择最后两个日期 .形成以下结果
这将带来错误的结果,即,即使我们加入
Id
,它也只会带来Details
表中最新的两个日期数据,而不管Id
. 所以正确的解决方案是使用OUTER APPLY
.形成以下所需结果
2. When we need LEFT JOIN functionality using functions.
当我们需要从
Master
表和function
获取结果时,OUTER APPLY
可以用作LEFT JOIN
的替代 .功能就在这里 .
产生了以下结果
CROSS APPLY
或OUTER APPLY
可用于在解锁时保留NULL
值,这些值是可互换的 .考虑一下你有下表
当您使用
UNPIVOT
将FROMDATE
ANDTODATE
带到一列时,它将默认消除NULL
值 .产生以下结果 . 请注意,我们已经错过了
Id
的记录3
在这种情况下,
CROSS APPLY
或OUTER APPLY
将是有用的形成以下结果并保留
Id
,其值为3
一个真实的例子是,如果您有一个调度程序,并希望查看每个计划任务的最新日志条目 .
要回答上述问题,请举例说明:
现在使用执行计划运行两个查询 .
您可以看到外部应用查询更有效 . (无法附上计划,因为我是新用户... Doh . )
APPLY
的一些用途是......1) Top N per group queries(某些基数可能更有效)
2) 为外部查询中的每一行调用一个表值函数
3) Reusing a column alias
4) Unpivoting more than one group of columns
假设违反表结构的1NF ....
使用2008
VALUES
语法的示例 .在2005年,可以使用
UNION ALL
代替 .