我试图在这个论坛上搜索答案,但似乎找不到答案。
我的问题:我有3张桌子。一个有物品,一个有正在进行的交付,另一个有送货。
表格称为项目:
id | item_name
----------------
1 | Bike
2 | Helmet
3 | Pedal
4 | Light
表格称为ingoing:
id | item_id | quantity
-----------------------
1 | 2 | 5
2 | 3 | 2
3 | 4 | 1
4 | 1 | 5
5 | 2 | 4
6 | 1 | 6
7 | 3 | 5
表称为传出:
id | item_id | quantity
-----------------------
1 | 3 | 2
2 | 1 | 1
3 | 2 | 3
4 | 3 | 4
5 | 1 | 2
6 | 2 | 1
7 | 4 | 1
我想要做的是通过从正在进行的货物中减去货物的总交货量来获得库存总量,并按最少量的物品订购。
也许有更好的方法可以做到这一点?
这是我收到的查询,但SUM金额不正确。有人可以帮助我并解释为什么SUM数量不正确,我应该如何以最好的方式解决这个问题?
SELECT items.id AS ID,
items.item_name,
Sum(ingoing.quantity) - Sum(outgoing.quantity) AS InStock
FROM items
LEFT JOIN ingoing
ON ingoing.item_id = items.id
LEFT JOIN outgoing
ON outgoing.item_id = items.id
GROUP BY ID
ORDER BY InStock ASC
这是我想要的结果:
ID | item_name | InStock
---------------------------
4 | Light | 0
3 | Pedal | 1
2 | Helmet | 5
1 | Bike | 8
我得到了什么:
ID | item_name | InStock
---------------------------
4 | Light | 0
3 | Pedal | 2
2 | Helmet | 10
1 | Bike | 16
答案 0 :(得分:1)
很容易忘记连接的乘法效应。当您遇到这样的问题时,请在过滤/分组之前检查连接的结果:
SELECT items.id,
items.item_name,
ingoing.id AS ingoing,
outgoing.id AS outgoing
FROM items
LEFT JOIN ingoing
ON ingoing.item_id = items.id
LEFT JOIN outgoing
ON outgoing.item_id = items.id
在sqlfiddle上查看。
如您所见,结果集包含多个具有相同ingoing.id
值的记录,以及具有相同outgoing.id
值的多个记录。这是因为特定项目的每个输入记录都与该项目的每个传出记录一起加入:因此结果集中有4个踏板(2个输入x 2输出)等。
在加入之前按项目汇总每个表格(从而确保每个项目在联接的每一侧只有1条记录)将实现您所追求的目标:
SELECT items.id AS ID,
items.item_name,
ingoing.quantity - outgoing.quantity AS InStock
FROM items
LEFT JOIN (
SELECT item_id AS id, SUM(quantity) AS quantity
FROM ingoing
GROUP BY item_id
) AS ingoing USING (id)
LEFT JOIN (
SELECT item_id AS id, SUM(quantity) AS quantity
FROM outgoing
GROUP BY item_id
) AS outgoing USING (id)
ORDER BY InStock ASC
在sqlfiddle上查看。
请注意,只有一个基本的库存变动表,你的问题会大大简化,正数表示一个方向的运动,负数表示相反方向的运动:然后整个表的简单分组总和会产生你想要的结果。
答案 1 :(得分:0)
尝试此查询:
SELECT items.id AS ID, items.item_name, (SELECT SUM(quantity) from ingoing
WHERE ingoing.item_id = items.id) - (SELECT SUM(quantity) from outgoing WHERE
outgoing.item_id = items.id) AS InStock FROM items ORDER BY InStock ASC;