Sql 具有两个左连接的SUM的问题

Sql 具有两个左连接的SUM的问题,sql,sql-server,join,left-join,Sql,Sql Server,Join,Left Join,在下面的查询中,当我有两个左连接时,我遇到了问题。发生的情况是两个左联接的和都不正确。当我删除第二个左连接时,查询将正确运行。如何使用第二个左联接运行此查询 SELECT o.IdNoLocation, COUNT(DISTINCT o.EncodedId) AS "Frequency", ISNULL(SUM(o.Subtotal), 0) AS "Spend", ISNULL(SUM(os.Amount), 0) AS "Surcharges", ISNULL(SUM(od.Amount

在下面的查询中,当我有两个左连接时,我遇到了问题。发生的情况是两个左联接的和都不正确。当我删除第二个左连接时,查询将正确运行。如何使用第二个左联接运行此查询

SELECT o.IdNoLocation,
COUNT(DISTINCT o.EncodedId) AS "Frequency", 
ISNULL(SUM(o.Subtotal), 0) AS "Spend", 
ISNULL(SUM(os.Amount), 0) AS "Surcharges",
ISNULL(SUM(od.Amount), 0) AS "Discounts" 
FROM ((tblOrder o
LEFT JOIN tblOrderSurcharge os ON o.OrderId=os.OrderId) 
LEFT JOIN tblOrderDiscount od ON o.OrderId=od.OrderId)
WHERE 
o.BusinessDate BETWEEN '2014-01-01' AND '2014-12-31'
AND o.IdNoLocation <> 'X'
GROUP BY o.IdNoLocation

当TBlorderSource或tblOrderDiscount中有多个相关行时,这是预期结果。。。这两个表中的行之间有一个隐式的半交叉连接

如果您需要在单个语句中返回总计,有几种方法可以解决此问题

一个选项是使用内联视图执行合计,然后合并行。基本上,运行单独的查询以从每个表中获取总计,然后在唯一的键上组合结果。例如:

SELECT o.IdNoLocation
     , o.Frequency
     , ISNULL(o.Spend, 0)       AS Spend
     , ISNULL(s.Surcharges), 0) AS Surcharges
     , ISNULL(s.Discounts), 0)  AS Discounts
  FROM ( SELECT ooo.IdNoLocation
              , COUNT(DISTINCT ooo.EncodedId) AS Frequency
              , SUM(ooo.Subtotal) AS Spend
           FROM tblOrder ooo
          WHERE ooo.BusinessDate BETWEEN '2014-01-01' AND '2014-12-31'
            AND ooo.IdNoLocation <> 'X'
         GROUP BY ooo.IdNoLocation
       ) o
  LEFT
  JOIN ( SELECT oso.IdNoLocation
              , SUM(oss.Amount) AS Surcharges
           FROM tblOrderSurcharge oss
           JOIN tblOrder oso
             ON oso.OrderId = oss.OrderId
          WHERE oso.BusinessDate BETWEEN '2014-01-01' AND '2014-12-31'
            AND oso.IdNoLocation <> 'X'
          GROUP BY oso.IdNoLocation
       ) s
    ON s.IdNoLocation = o.IdNoLocation
  LEFT
  JOIN ( SELECT odo.IdNoLocation
              , SUM(odd.Amount) AS Discounts
           FROM tblOrderDiscount odd
           JOIN tblOrder odo
             ON odo.OrderId = odd.OrderId
          WHERE odo.BusinessDate BETWEEN '2014-01-01' AND '2014-12-31'
            AND odo.IdNoLocation <> 'X'
          GROUP BY odo.IdNoLocation
       ) d
    ON d.IdNoLocation = o.IdNoLocation
这不是测试,只是桌面检查。运行每个内联视图查询o、s、d,并验证每个查询的结果是否与预期一致。然后,运行整个查询,以合并行。。。在外部查询中,我们将进行外部联接,处理缺少的行,并用零替换空值


另一个选项是在选择列表中使用相关子查询

要查看此操作不起作用的原因,请运行此查询:

SELECT o.IdNoLocation,
o.EncodedId AS "Frequency", 
o.Subtotal AS "Spend", 
os.Amount AS "Surcharges",
od.Amount AS "Discounts" 
FROM ((tblOrder o
LEFT JOIN tblOrderSurcharge os ON o.OrderId=os.OrderId) 
LEFT JOIN tblOrderDiscount od ON o.OrderId=od.OrderId)
WHERE 
o.BusinessDate BETWEEN '2014-01-01' AND '2014-12-31'
AND o.IdNoLocation <> 'X'

“正确”的答案是使用一个表来计算附加费和折扣。我认为这不再是一个选项,但您可以使用在两个表之间执行“全部并集”的视图来伪造它。

您可以提供示例数据和预期结果吗?由于联接而导致的膨胀总和表示您的条件不足以匹配表1:1之间的行。o.OrderID在tblOrderDiscount中是否可以有多个条目?是的,一个订单o.OrderID可以从tblOrderDiscount应用多个折扣。