如何连接三个表以获得总和
Posted
技术标签:
【中文标题】如何连接三个表以获得总和【英文标题】:How to join three tables to get Sum 【发布时间】:2015-04-26 14:47:49 【问题描述】:我有三个表:Products、Purchase、Invoice
产品表: Productct_no 名称 1 A 2 B 3 C
采购表: Purchase_no Product_no 数量 001 1 81 002 2 150 003 3 10
发票表: 发票编号 产品编号 数量 001 1 20 002 2 10 003 3 10
我想获取每个产品的采购数量和发票数量,我使用了以下查询
选择 PR.product_no, sum(P.qty),sum(I.qty) FROM 产品公关 LEFT JOIN invoice I ON I.product_no=PR.product_no LEFT JOIN 购买 P ON P.product_no=PR.product_no 按 PR.product_no 分组product_no sum(P.qty) sum(I.qty) 001 162 160 002 150 50 003 10 10
编辑:预期结果 product_no sum(P.qty) sum(I.qty) 001 81 20 002 150 10 003 10 10
我的查询给了我错误的响应(数量总和错误),请帮助我更正我的查询以正确获得结果。谢谢
【问题讨论】:
您的预期结果是什么? 省略总和和分组依据,看看返回了什么结果,这样你就知道你在求和什么数据。 无论如何看起来像是一对一的映射。分组似乎是多余的 这里好像有几个错别字,不清楚你的意思。在您的结果表中,您有两次sum(P.qty)
。也很清楚你想要什么;每个产品在每个表上只存在一次,所以不清楚为什么要总和而不是结果?
@pala_ 我认为这不是现实中的 1:1 映射。可能有其他发票和相同产品的购买,该示例仅显示 1:1 映射。我怀疑上面显示的数据不完整。此外,如果任一左连接返回多于一行(我怀疑它实际上是这样),则由于扇出,这是执行此查询的错误方法。
【参考方案1】:
根据所提供的信息,我认为您的示例数据并不真正是您所拥有的。我在这里最好的猜测是,您的查询正在对这些连接中的一个或两个进行扇出,这会弄乱您的总和。您需要分别对它们求和,否则这些连接中的任何一个中的附加行都会扇出另一个连接,从而在总和中复制您的结果。这在您的结果中很明显,因为 001 看起来是双倍的(即使您的示例数据没有显示它)。
这样可以确保总和彼此独立:
SELECT PR.product_no,
( SELECT sum(I.qty)
FROM invoice I
WHERE I.product_no=PR.product_no ) invoice_qty,
( SELECT sum(P.qty)
FROM purchase P
WHERE P.product_no=PR.product_no ) purchase_qty
FROM products PR
【讨论】:
非常感谢,您的回答对我有帮助。【参考方案2】:我认为您的 GROUP BY 有问题。在这种情况下我会做这样的事情
SELECT P.Product_no, Inv.InvProdSum, Pur.PurProdSum
FROM Product P
LEFT JOIN (SELECT Product_no, SUM(Qty) AS InvProdSum
FROM Invoice
GROUP BY Product_no) AS Inv
ON P.Product_no = Inv.Product_no
LEFT JOIN (SELECT Product_no, SUM(Qty) AS PurProdSum
FROM Purchase
GROUP BY Product_no) AS Pur
ON P.Product_no = Pur.Product_no
这是http://sqlfiddle.com/#!9/731a5/1的SQL Fiddle
注意我在这里添加了一些额外的值来测试它是如何工作的......
GL!
【讨论】:
这并没有给我预期的结果,我使用 Group by 因为我在 Invoice 和 Purchase 表中有很多 product_no 记录,我简化了这个问题的表。谢谢 @Azmath 我不明白,我得到的结果与您在测试时想要得到的结果完全相同...我知道您想对表 Invoice 和 Purchase 中具有相同 product_no 的所有值求和并将其显示在我的查询完全执行的一张表中...here...无论如何祝你好运,我希望你能找到你的解决方案:) 您的回答有效,这是我的错,我的问题很混乱,但您解决了非常感谢。 @Azmath 是的,我看到你找到了解决方案 woot 解决它:)。很高兴你做到了,这很重要。【参考方案3】:这是我没有子查询的解决方案:
with
product(product_no, name) as (values
(1, 'A'),
(2, 'B'),
(3, 'C')
),
purchase(purchase_no, product_no, qty) as (values
('001', 1, 81),
('002', 2, 150),
('003', 3, 10),
('004', 1, 1000)
),
invoice(invoice_no, product_no, qty) as (values
('001', 1, 20),
('002', 2, 10),
('003', 3, 10),
('004', 2, 5000)
),
mixed as
(select d.product_no,
purchase_no, p.qty as qty_purchase,
invoice_no, i.qty as qty_invoice,
row_number() over(partition by purchase_no) as rn_purchase,
row_number() over(partition by invoice_no) as rn_invoice
from product d
left join purchase p on p.product_no = d.product_no
left join invoice i on i.product_no = d.product_no
)
select product_no,
sum((case when rn_purchase = 1 then 1 else 0 end) * qty_purchase) as sum_purchase,
sum((case when rn_invoice = 1 then 1 else 0 end) * qty_invoice) as sum_invoice
from mixed
group by product_no
order by product_no
;
结果:
product_no|sum_purchase|sum_invoice|
----------|------------|-----------|
1| 1081| 20|
2| 150| 5010|
3| 10| 10|
【讨论】:
以上是关于如何连接三个表以获得总和的主要内容,如果未能解决你的问题,请参考以下文章