SUM()返回不正确的值

时间:2018-08-02 22:44:39

标签: mysql sum

我有一些桌子,产品,收货和退货。传出和传入有两行,这让您对发生的事情有所了解,因为我从查询中获得的结果是应有结果的两倍

SELECT products.ProductName, products.StartingInventory,
        sum(incoming.NumReceived) invReceived, sum(outgoing.NumberShipped) invShipped,
        products.InventoryOnHand, products.MinimumRequired 
from incoming, products, outgoing 
where incoming.ProductId = products.id and outgoing.ProductId = products.id 
group by products.id

有问题的两个值是invReceived和invShipped。这是传入表:

| id  SupplierID ProductID NumReceived PurchaseDate |
| 1   1          1         6           2018-02-01   |
| 2   1          1         7           2017-05-09   |

和传出表格

|id First    Middle    Last        ProductId NumberShipped OrderDate |
|1  Dan      Smith     Agent       1         6             2018-02-01|
|2  Bethany  Richards  Richardson  1         15            2018-04-20|

结果为invReceived:26和invShipped 36,但应分别为13和18。

1 个答案:

答案 0 :(得分:1)

删除group by和聚合函数(即sum)可以发现问题所在。

sqlite> SELECT products.ProductName, products.StartingInventory,
   ...>         incoming.NumReceived invReceived, outgoing.NumberShipped invShipped,
   ...>         products.InventoryOnHand, products.MinimumRequired 
   ...> from incoming, products, outgoing 
   ...> where incoming.ProductId = products.id and outgoing.ProductId = products.id 
   ...> 
   ...> ;
ProductName  StartingInventory  invReceived  invShipped  InventoryOnHand  MinimumRequired
-----------  -----------------  -----------  ----------  ---------------  ---------------
Dell         290                6            3           300              10             
Dell         290                7            3           300              10             
Dell         290                6            15          300              10             
Dell         290                7            15          300              10    

我正在SQLite中进行此操作,但与MySQL应该没有什么区别。

行被计数两次。通过选择ID,我们可以更清楚地看到问题。

sqlite> SELECT products.id, incoming.id, outgoing.id
   ...> from incoming, products, outgoing 
   ...> where incoming.ProductId = products.id and outgoing.ProductId = products.id 
   ...> ;
id          id          id        
----------  ----------  ----------
1           1           1         
1           2           1         
1           1           2         
1           2           2         

有几种解决方法。 One is from @JerryJermiah in the comments

SELECT products.id, 
    (select sum(incoming.NumReceived)
     from incoming
     where incoming.productid = products.id),
    (select sum(outgoing.NumberShipped)
     from outgoing
     where outgoing.productid = products.id)
from products;

这一次获取每个产品,然后对每个产品进行子选择以获取NumReceived和NumberShipped。

您也可以执行类似的操作,但对子查询进行联接。

select p.id, ig.NumReceived, og.NumShipped
from products p
join (
    select productid, sum(NumReceived) as NumReceived
    from incoming
    group by productid
) as ig on p.id = ig.productid
join (
    select productid, sum(NumberShipped) as NumShipped
    from outgoing
    group by productid
) as og on p.id = og.productid

可能更快,因为SQL只需要执行三个查询,而不是每个产品执行两个查询。也许SQL优化会解决这个问题。您必须进行基准测试。