我有桌子交付和桌面订单。可以将多个订单链接到交货。几天前,我问question 有关如何获得特定交货的订单金额总和,并迅速了解如何。 (再次感谢。)
现在我们也添加了一个结算表,就像订单一样,可以有多个结算链接到一个交货(通过交货ID,就像订单一样),我正在尝试获得价值的总和同样。我想我也会使用相同的策略和LEFT JOIN结算表,但问题是,当只有一个结算链接到特定的交付时,SUM(s.amount)返回实际值的两倍。
我试过玩GROUP BY无济于事。谁能告诉我我做错了什么?
提前致谢!
PS:这是我使用的查询,当只有一个结算时,它会返回结算金额的双倍值:
SELECT
d.id,
SUM(o.goods_amount) AS amount,
SUM(s.amount) AS settlementAmount,
FROM delivery d
LEFT JOIN order o
ON d.id = o.delivery_id
LEFT JOIN settlement s
ON d.id = s.delivery_id
WHERE d.id = *deliveryId*
GROUP BY d.id;
答案 0 :(得分:1)
正如Spencer评论的那样,你得到了一种交叉加入的结果。让我们看一下这个样本数据。
Delivery Table
ID Delivered_On
1 2016-07-01
2 2016-07-02
Orders Table
id Deliveries_id Amount
1 1 100
2 1 200
3 1 300
4 2 75
Now your Settlements table
Settlements Table
id Delivery_id Amount
1 1 525 (explicitly wrong amount to show result)
2 1 75
您的查询是按照每个交付ID进行汇总,但是(左)加入了订单表和结算表。因此,每个表中存在的许多记录将被交叉连接,因此对于交货ID = 1,您有3个订单但是1个结算。因此,结算记录也将加入到每个订单表中,而不仅仅是交货表,从而得到3 * 525或$ 1575 PLUS 3 * 75 = 225美元的结果,总计1800美元。您的订单总和将恰好为600美元。
要解决此问题,您可能需要预先聚合每个辅助表,以便每次传递仅返回1个摘要记录并加入THOSE结果。为了防止查询所有订单和结算,我加入交货表以确定所有订单和日期范围内的相同日期范围。
SELECT
d.id AS delivery_id,
sumOrd.Amount as OrderAmount,
sumStl.Amount as SettlementAmount
from
delivery d
LEFT JOIN
( select
d2.id,
SUM(o.amount) AS OrderAmount
from
delivery d2
JOIN order o
ON d2.id = o.deliveries_id
WHERE
d2.delivered_on >= '2016-06-10'
and d2.delivered_on < '2016-06-11'
GROUP BY
d2.id ) sumOrd
on d.id = sumOrd.id
LEFT JOIN
( select
d2.id,
SUM(s.amount) AS SettlementAmount
from
delivery d2
JOIN Settlement s
ON d2.id = s.delivery_id
WHERE
d2.delivered_on >= '2016-06-10'
and d2.delivered_on < '2016-06-11'
GROUP BY
d2.id ) sumStl
on d.id = sumStl.id
where
d.delivered_on >= '2016-06-10'
and d.delivered_on < '2016-06-11'
答案 1 :(得分:0)
首先使用以下查询验证您获得的结果是否正确
SELECT
d.id,
IFNULL(o.goods_amount,0) AS amount,
IFNULL(s.amount,0) AS settlementAmount,
FROM delivery d
LEFT JOIN order o
ON d.id = o.delivery_id
LEFT JOIN settlement s
ON d.id = s.delivery_id
WHERE d.id = *deliveryId*
然后请检查此查询
SELECT
d.id,
SUM(IFNULL(o.goods_amount,0)) AS amount,
SUM(IFNULL(s.amount,0)) AS settlementAmount,
FROM delivery d
LEFT JOIN order o
ON d.id = o.delivery_id
LEFT JOIN settlement s
ON d.id = s.delivery_id
WHERE d.id = *deliveryId*
GROUP BY d.id;