连接是否会比此子查询更好

时间:2014-03-24 00:25:03

标签: sql sql-server

我创建了一个表变量,它已经填充了我在存储过程中处理的一些Overpayments的主键。这个表可以在其中包含ZERO和10行。

对于每个'OverpaymentID',我需要计算已经对此债务进行的付款的价值。为了做到这一点,我使用临时表作为根,然后使用子查询来连接我需要的其他表中的行,并将该子查询中的值相加如下所示:

UPDATE op
SET op.PaymentsTotal = breakdown.amt
FROM @Overpayments op
INNER JOIN (
  SELECT op.OverpaymentID, SUM(da.Amount) AS amt
  FROM dbo.OverpaymentPlan op
  INNER JOIN dbo.OverpaymentPlanSchedule ops
  ON ops.OverpaymentPlanID = op.OverpaymentPlanID
  INNER JOIN dbo.PaymentAllocation pa
  ON pa.OverpaymentPlanScheduleID = ops.OverpaymentPlanScheduleID
  INNER JOIN dbo.DailyAllocation da
  ON da.PaymentAllocationID = pa.PaymentAllocationID
  GROUP BY op.OverpaymentID
) breakdown
ON breakdown.OverpaymentID = op.OverpaymentID

我担心这可能效率低下。我正确地说,因为子查询没有WHERE子句 - 它将在我的表中的所有行中总结所有值(这些表有数百万条记录),然后只选择我临时表所需的几个?

'JOIN'方法的唯一问题是,当我尝试添加SUM时,我在更新中收到错误,说我不能使用SUM。

或者,SQL可以看到我对子查询所做的JOIN,只能获得相关的行吗?

或者......如果没有子查询,我应该找到一种方法吗?我认为可以通过加入来完成吗?

1 个答案:

答案 0 :(得分:1)

你是对的。由于group by语句,子查询将被完全评估。子查询不一定与整体查询分开优化,但根据我的经验,这对于聚合来说是正确的。

解决此问题的一种简单方法是使用cross apply

UPDATE op2
    SET op.PaymentsTotal = breakdown.amt
    FROM @Overpayments op2 CROSS APPLY
         (SELECT op.OverpaymentID, SUM(da.Amount) AS amt
          FROM dbo.OverpaymentPlan op INNER JOIN
               dbo.OverpaymentPlanSchedule ops
               ON ops.OverpaymentPlanID = op.OverpaymentPlanID INNER JOIN
               dbo.PaymentAllocation pa
               ON pa.OverpaymentPlanScheduleID = ops.OverpaymentPlanScheduleID INNER JOIN
               dbo.DailyAllocation da
               ON da.PaymentAllocationID = pa.PaymentAllocationID
          WHERE op2.OverpaymentID = op.OverpaymentID
          GROUP BY op.OverpaymentID
         ) breakdown;

您也可以使用相关的子查询。