我有一些桌子,产品,收货和退货。传出和传入有两行,这让您对发生的事情有所了解,因为我从查询中获得的结果是应有结果的两倍
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。
答案 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优化会解决这个问题。您必须进行基准测试。