SQL OUTER JOIN列总和返回两倍的量

时间:2014-11-16 23:02:37

标签: sql sql-server sum outer-join

我有一个显示查询,基本上显示库存,订单和保留库存。除了一个部分之外一切都很好 - 重量和数量的总和会返回一倍的结果(仅在订购量有限的情况下)。我确定我已经塞满了我的联合,但我无法弄清楚如何。

当前输出(加倍):

PartNo                     Branch SOHWeight SOHQty ReservedQty SOOEa SOOTo AvgCost type product grade coating finish thickness width length dim1 dim2 Notes                                                                                                                                                                                                                                                            ClassFBR ClassFME ClassFSY AltoQty
-------------------------- ------ --------- ------ ----------- ----- ----- ------- ---- ------- ----- ------- ------ --------- ----- ------ ---- ---- -----
B-254-304---5--40-40-6000  FME    0.33      18     NULL        NULL  1.5   68.7494 B    ANGLE-E 304           NULL   5         NULL  6000   40   40   NULL                                                                                                                                                                                                                                                             C        A        B        NULL
Warning: Null value is eliminated by an aggregate or other SET operation.

预期输出完全相同,但SOHWeight和SOHQty应减半(与当前输出相比)

注意:

  • StockOnHand将拥有许多具有相同ProductDesc(部件号)
  • 的PackNoID
  • 对同一个PackNoID可以有多个预订
SELECT dbo.tblProducts.PartNo,
       'FME'                                                                                                                                                                                                AS Branch,
       SUM(sOh.Weight)                                                                                                                                                                                      AS SOHWeight,
       SUM(sOh.Quantity)                                                                                                                                                                                    AS SOHQty,
       SUM(dbo.tblReserveDetail.Quantity)                                                                                                                                                                   AS ReservedQty,
       SUM(iif(dbo.tblPurchaseOrderDetail.QuantityUnit = 'TO', NULL, dbo.tblPurchaseOrderDetail.QuantityAmount))                                                                                            AS SOOEa,
       SUM(iif(dbo.tblPurchaseOrderDetail.QuantityUnit = 'TO', dbo.tblPurchaseOrderDetail.QuantityAmount, NULL))                                                                                            AS SOOTo,
       SUM(IIF(SoH.TYPE IN ( 'C', 'SC' ), SoH.COST * SoH.WEIGHT, SoH.COST * SoH.QUANTITY) + PROCESSINGCOST + PROCESSINGFREIGHT + Packaging) / SUM(IIF(SoH.TYPE IN ( 'C', 'SC' ), sOh.weight, sOh.Quantity)) AS AvgCost,
       tblProducts.type,
       tblProducts.product,
       tblProducts.grade,
       tblProducts.coating,
       tblProducts.finish,
       tblProducts.thickness,
       tblProducts.width,
       tblProducts.length,
       tblProducts.dim1,
       tblProducts.dim2,
       tblProducts.Notes,
       tblProducts.ClassFBR,
       tblProducts.ClassFME,
       tblProducts.ClassFSY,
       SUM(IIF(SoH.STATUS = 'SC', SoH.QUANTITY, NULL))                                                                                                                                                      AS AltoQty
FROM   DBO.tblProducts
       LEFT OUTER JOIN dbo.tblStockOnHand SoH
         ON tblProducts.PartNo = SOH.ProductDesc
            AND SoH.Status IN ( 'I', 'R', 'SC' )
            AND SoH.branch = 'FME'
       LEFT OUTER JOIN dbo.tblReserveDetail
                       RIGHT OUTER JOIN dbo.tblReserveHeader
                         ON dbo.tblReserveHeader.ID = dbo.tblReserveDetail.ReserveID
                            AND tblReserveHeader.Completed = 0
                            AND tblReserveHeader.Cancelled = 0
         ON SOH.PACKNOID = tblReserveDetail.PacknoID
       LEFT OUTER JOIN tblPurchaseOrderDetail
         ON dbo.tblPurchaseOrderDetail.ProductDesc = dbo.tblProducts.PartNo
            AND ( dbo.tblPurchaseOrderDetail.Status = N'O'
                   OR dbo.tblPurchaseOrderDetail.Status = N'PD' )
            AND tblPurchaseOrderDetail.branch = 'FME'
GROUP  BY dbo.tblProducts.PartNo,
          tblProducts.type,
          tblProducts.product,
          tblProducts.grade,
          tblProducts.coating,
          tblProducts.finish,
          tblProducts.thickness,
          tblProducts.width,
          tblProducts.length,
          tblProducts.dim1,
          tblProducts.dim2,
          tblProducts.Notes,
          tblProducts.ClassFBR,
          tblProducts.ClassFME,
          tblProducts.ClassFSY 

样本数据(剥离): tblStockOnHand:

PackNoID    Status  Weight  Quantity    Cost    ProcessingCost  ProcessingFreight   Packaging   Branch  tblstockonhand.ProductDesc
157220  I   0.165   9   $68.47  $0.00   $2.48   $0.00   FME B-254-304---5--40-40-6000
158620  I   0.01839825  1   $64.27  $0.00   $4.72   $0.00   FSY B-254-304---5--40-40-6000

tblPurchaseOrderDetail

RecordId    Status  OrderNumber ItemNumber  QuantityAmount  QuantityUnit    PriceQuantity   PriceUnit   Branch  ProductDesc
6976    FD  4441    18  0.25    TO  3790    TO  FBR B-254-304---5--40-40-6000
6936    O   4439    23  0.5 TO  3790    TO  FME B-254-304---5--40-40-6000
6912    FD  4437    1   20  EA  75.96   EA  FSY B-254-304---5--40-40-6000

tblPurchaseOrderHeader

Status  OrderNumber Branch
O   4439    FME

tblProducts

PartNo  ClassFBR    ClassFME    ClassFSY    Notes   Type    Product Grade   Finish  Coating Thickness   Width   Length  Dim1    Dim2
B-254-304---5--40-40-6000   C   A   B       B   ANGLE-E 304         5       6000    40  40

2 个答案:

答案 0 :(得分:0)

没有查看详细信息,右外部加入是可疑的。右外连接总是可以用左外连接替换,并且将两者一起使用可能会产生令人困惑的查询。这可能是造成双重结果的原因。尝试重构,以便所有连接都留在外部而不是组合。

答案 1 :(得分:0)

最后钉了它,据我所知,我必须在OUTER加入它们之前对子连接进行子查询,否则不是分组/求和,它们将为返回的每条记录求和。我知道可怕的解释,但这是最终结果查询。感谢任何看过的人。

SELECT  dbo.tblProducts.PartNo, 'FME' AS Branch, SUM(sOh.Weight) AS SOHWeight, SUM(sOh.Quantity) AS SOHQty, 
        ReservedQty, SOOEa,SOOTo
        ,sum(IIF(SoH.TYPE IN ('C','SC'),SoH.COST*SoH.WEIGHT,SoH.COST*SoH.QUANTITY)+soh.PROCESSINGCOST+soh.PROCESSINGFREIGHT+soh.Packaging)/SUM(IIF(SoH.TYPE IN ('C','SC'),sOh.weight,sOh.Quantity)) AS AvgCost
        ,tblProducts.type,tblProducts.product,tblProducts.grade,tblProducts.coating,tblProducts.finish,tblProducts.thickness,tblProducts.width,tblProducts.length,tblProducts.dim1,tblProducts.dim2,tblProducts.Notes,tblProducts.ClassFBR,tblProducts.ClassFME,tblProducts.ClassFSY
        ,SUM(IIF(SoH.STATUS='SC',SoH.QUANTITY,NULL)) AS AltoQty
FROM 
        dbo.tblProducts 
        LEFT OUTER JOIN
        dbo.tblStockOnHand SoH  
        ON tblProducts.PartNo = SOH.ProductDesc AND SoH.Status IN ('I', 'R','SC') AND SoH.branch='FME' 
        LEFT OUTER JOIN
            (SELECT SUM(tblReserveDetail.Quantity) AS ReservedQty, ProductDesc
            FROM dbo.tblReserveDetail INNER JOIN tblReserveHeader ON dbo.tblReserveHeader.ID = dbo.tblReserveDetail.ReserveID INNER JOIN tblStockOnHand ON tblReserveDetail.PacknoID=tblStockOnHand.PackNoID
            WHERE tblReserveHeader.Completed=0 AND tblReserveHeader.Cancelled =0 AND BRANCH='FME'
            GROUP BY ProductDesc) RES
        ON SoH.ProductDesc = RES.ProductDesc 
        LEFT OUTER JOIN 
            (SELECT tblPurchaseOrderDetail.ProductDesc,SUM(iif(QuantityUnit='TO',null,QuantityAmount)) AS SOOEa,SUM(iif(QuantityUnit='TO',QuantityAmount,null)) AS SOOTo 
            FROM tblPurchaseOrderDetail WHERE
            (dbo.tblPurchaseOrderDetail.Status = N'O' OR dbo.tblPurchaseOrderDetail.Status = N'PD') AND tblPurchaseOrderDetail.branch='FME'
            GROUP BY tblPurchaseOrderDetail.ProductDesc) PoD
        ON PoD.ProductDesc = dbo.tblProducts.PartNo
GROUP BY dbo.tblProducts.PartNo,tblProducts.type,tblProducts.product,tblProducts.grade,tblProducts.coating,tblProducts.finish,tblProducts.thickness,tblProducts.width,tblProducts.length,tblProducts.dim1,tblProducts.dim2,tblProducts.Notes,tblProducts.ClassFBR,tblProducts.ClassFME,tblProducts.ClassFSY,SOOEa,SOOTo,ReservedQty