在此业务情景中,所有承包商每天都会为各种库存项目下订单。此数据存储在ContractorOrder表中。收到库存后,会记录这些值并将其保存在ContractorStock表中。如果订单项在ContractorOrder表中不存在,则不可能出现在ContractorStock表中。
但有时,某些物品未送达,或者交付的数量不正确,或者承包商忘记下订单。为了检查这一点,我写了这两个查询(忽略Sums相同但各个行项不同的情况 - 这只是一个简化的例子):
SELECT C.ContractorId
, C.ContractorName
, Sum(CO.Quantity) OrderQuantity
, Sum(CS.Quantity) ContractorQuantity
FROM [Contractor] C
LEFT JOIN ContractorOrder CO
ON C.ContractorId = CO.ContractorId
AND CO.Date = @date
LEFT JOIN
(
ContractorStock CS
JOIN StockCode SC
ON CS.StockCodeId = SC.StockCodeId
AND CS.Date = @date
)
ON CS.ContractorId = C.ContractorId
AND SC.StockCode = CO.StockCode
GROUP BY C.ContractorId
, C.ContractorName
http://sqlfiddle.com/#!6/55496/5
和
SELECT C.ContractorId
, C.ContractorName
, Sum(CO.Quantity) OrderQuantity
, Sum(CS.Quantity) ContractorQuantity
FROM [Contractor] C
LEFT JOIN ContractorOrder CO
ON C.ContractorId = CO.ContractorId
AND CO.Date = @date
LEFT JOIN
(
SELECT CS.ContractorId
, SC.StockCode
, CS.Quantity
FROM ContractorStock CS
JOIN StockCode SC
ON CS.StockCodeId = SC.StockCodeId
AND CS.Date = @date
) CS
ON CS.ContractorId = C.ContractorId
AND CS.StockCode = CO.StockCode
GROUP BY C.ContractorId
, C.ContractorName
http://sqlfiddle.com/#!6/55496/2
两者都返回相同的结果,但执行计划略有不同。在这种情况下,这些查询在逻辑上是否相同?如果是,我应该更喜欢嵌套加入吗?
嵌套加入:
子查询:
答案 0 :(得分:0)
你刚刚证明了什么(当涉及到不同类型的查询时)你应该让SQL Server找出最好的计划(因为SQL版本上升,引擎会越来越好,找到最好的查询计划)而你应该专注于编写产生基于设置的正确结果的SQL。
我看到的唯一区别是计算缩放器步骤接近总计划的0%,因此不值得花费大量时间来消除该步骤。
在过去(SQL Server 2000之前版本),如果你编写了连接和子查询,它实际上很重要。现在,在绝大多数情况下,将子查询更改为连接或反之亦然。
您始终希望避免逐行操作,并在可能的情况下使用seek进行替换,但是一旦您完成了此操作。