【问题标题】:Left join returning bad values左连接返回错误值
【发布时间】:2015-02-10 16:18:16
【问题描述】:

我不太擅长 SQL 查询,但我尝试写这个:

SELECT DATEPART(YY,Orders.OrderDate) as Year,
DATEPART(MM,Orders.OrderDate) as Month,
(SUM(case when OrderDetails.ProductCode = 'XXX' then 
OrderDetails.ProductPrice else 0 end) + SUM(Orders.Total))
AS XXX 
FROM Orders 
LEFT JOIN OrderDetails ON Orders.OrderID = OrderDetails.OrderID 
WHERE Orders.OrderStatus = 'Shipped' 
GROUP BY DATEPART(MM,Orders.OrderDate), DATEPART(YY,Orders.OrderDate) 
ORDER BY DATEPART(YY,Orders.OrderDate),DATEPART(MM,Orders.OrderDate)

OrderDetails 通过字段OrderID 链接到Orders 表。在这个SELECT 查询中,我试图在OrderDetails.ProductCodeXXX 时获取OrderDetails.ProductPrice 的总和,并将其添加到Orders.Total 以获得每个月/年的总金额。

除了一个问题(这可能是业余错误或已解决多次)之外,该查询正在运行。执行LEFT JOIN 时,OrderDetails 表可以有多个记录链接到Orders 表,这会在SUM(Orders.Total) 中抛出错误的结果。我已经隔离了这个问题,我似乎无法解决它。

谁能指出我正确的方向?

【问题讨论】:

  • 旁注:在GROUP BY/ORDER BY 中使用DATEPART(...) 将阻止优化器使用索引来完成查询的该部分,可能会使其非常慢。如果您可以改为创建可以加入的范围表(类似于我所做的in this answer,尽管您需要使用递归查询来创建范围),您应该能够进行索引可回答的比较。

标签: sql select sql-server-2005 group-by left-join


【解决方案1】:

如果我们假设XXX 产品在每个订单中最多只出现一次,那么这应该可行:

SELECT year(o.OrderDate) as Year, month(o.OrderDate) as Month,
       (COALESCE(SUM(od.ProductPrice), 0) + SUM(o.Total)) AS XXX 
FROM Orders o LEFT JOIN
     OrderDetails od
     ON o.OrderID = od.OrderID AND od.ProductCode = 'XXX'
WHERE o.OrderStatus = 'Shipped' 
GROUP BY year(o.OrderDate), month(o.OrderDate) 
ORDER BY year(o.OrderDate), month(o.OrderDate);

如果它可以出现多次,则将聚合的那部分移动到子查询中:

SELECT year(o.OrderDate) as Year, month(o.OrderDate) as Month,
       (COALESCE(XXX, 0) + SUM(o.Total)) AS XXX 
FROM Orders o LEFT JOIN
     (SELECT od.OrderId, SUM(od.ProductPrice) as XXX
      FROM OrderDetails od
      WHERE od.ProductCode = 'XXX'
      GROUP BY od.OrderId
     ) od
     ON o.OrderID = od.OrderID 
WHERE o.OrderStatus = 'Shipped' 
GROUP BY year(o.OrderDate), month(o.OrderDate) 
ORDER BY year(o.OrderDate), month(o.OrderDate);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 2011-07-22
    相关资源
    最近更新 更多