什么时候选择CROSS APPLY和EXISTS?

时间:2012-03-12 11:10:13

标签: sql sql-server join exists cross-apply

我读过,CROSS APPLY就像JOIN ..我认为JOIN也可以用EXISTS完成(相关子查询)

我很困惑,使用CROSS APPLY和EXISTS有什么区别?

什么时候应该针对EXISTS进行交叉申请?

2 个答案:

答案 0 :(得分:7)

CROSS APPLY不仅仅是一个JOIN。 JOIN在两组数据之间找到匹配(或不匹配)的行。 CROSS APPLY是一种针对您正在应用它的事物的每一行运行查询的方法。这可以作为一种过滤机制,就像JOIN的工作方式一样,但是它会对每一行应用一些东西,所以需要这样思考。

子查询中的EXISTS是一种完全不同的过滤机制。这是一种快速识别的方法,因为它会在找到某些东西时立即使其搜索短路。一般来说,您希望使用EXISTS的地方是您可能会对过滤条件产生影响,从而使搜索尽可能短。但是,EXISTS找不到所有匹配项。它只找到第一个匹配,然后停止搜索。

因此,虽然您可以从这三种不同的方法得到相同的结果,但按照定义使用它们,您通常是正确的。如果你真的在加入两组数据,请使用JOIN。如果要对数据集中的每一行运行进程(通常是过滤器),请使用CROSS APPLY。如果您想要对可能的正匹配进行快速过滤,请使用EXISTS。

答案 1 :(得分:0)

格兰特对这笔钱的反应是正确的 但从个人风格的角度来看,我只使用OUTER APPLY。 这是一个常见的模式,所有这三个都做同样的事情,但是通过使用外部应用,在验证时你可以简单地注释掉“WHERE ca2.HasAddress ='是'”并将ca2.HasAddress添加到主选择以验证您的过滤器正在删除您想要的记录,而其他两种过滤方法在行级别不提供相同的透明度。

SELECT c.CustomerID
FROM SalesLT.Customer c
OUTER APPLY (SELECT TOP 1 'Yes' HasAddress
             FROM SalesLT.CustomerAddress ca
             WHERE c.CustomerID = ca.CustomerID)
             ca2
WHERE ca2.HasAddress = 'Yes'

SELECT c.CustomerID 
FROM SalesLT.Customer c
CROSS APPLY (SELECT TOP 1 'Yes' HasAddress
             FROM SalesLT.CustomerAddress ca
             WHERE c.CustomerID = ca.CustomerID)
             ca2

SELECT c.CustomerID 
FROM SalesLT.Customer c
WHERE EXISTS (SELECT 1
             FROM SalesLT.CustomerAddress ca
             WHERE c.CustomerID = ca.CustomerID)