[英]Sum columns from two tables in sql
我有两个表,一个是成本表,另一个是付款表,成本表包含产品的成本和产品名称。
Cost Table
id | cost | name
1 | 100 | A
2 | 200 | B
3 | 200 | A
Payment Table
pid | amount | costID
1 | 10 | 1
2 | 20 | 1
3 | 30 | 2
4 | 50 | 1
现在我必须按相同的name
值对总费用求和,并按 costID 对总付款金额求和,如下面的查询
totalTable
name | sum(cost) | sum(amount) |
A | 300 | 80 |
B | 200 | 30 |
但是,我一直在使用下面的查询来解决这个问题,但我认为我做错了。
SELECT
b.name,
b.sum(cost),
a.sum(amount)
FROM
`Payment Table` a
LEFT JOIN
`Cost Table` b
ON
b.id=a.costID
GROUP by b.name,a.costID
如果有人能帮助我解决我的疑问或更好的想法,我将不胜感激。 谢谢
这应该有效:
select t2.name, sum(t2.cost), coalesce(sum(t1.amount), 0) as amount
from (
select id, name, sum(cost) as cost
from `Cost`
group by id, name
) t2
left join (
select costID, sum(amount) as amount
from `Payment`
group by CostID
) t1 on t2.id = t1.costID
group by t2.name
您需要在单独的查询中进行计算,然后将它们连接在一起。
name
asociated基于在付款cost_id
SELECT C.`name`, C.`sum_cost`, COALESCE(P.`sum_amount`,0 ) as `sum_amount`
FROM (
SELECT `name`, SUM(`cost`) as `sum_cost`
FROM `Cost`
GROUP BY `name`
) C
LEFT JOIN (
SELECT `Cost`.`name`, SUM(`Payment`.`amount`) as `sum_amount`
FROM `Payment`
JOIN `Cost`
ON `Payment`.`costID` = `Cost`.`id`
GROUP BY `Cost`.`name`
) P
ON C.`name` = P.`name`
输出
| name | sum_cost | sum_amount |
|------|----------|------------|
| A | 300 | 80 |
| B | 200 | 30 |
几个问题。 一方面,应该限定列引用,而不是聚合函数。
这是无效的:
table_alias.SUM(column_name)
应该:
SUM(table_alias.column_name)
此查询应返回您要查找的前两列:
SELECT c.name AS `name`
, SUM(c.cost) AS `sum(cost)`
FROM `Cost Table` c
GROUP BY c.name
ORDER BY c.name
当您向另一个表(例如Product Table
,其中costid
不是UNIQUE )引入连接时,您有可能生成(部分)笛卡尔积。
要查看它的样子,查看正在发生的事情,请删除GROUP BY
和聚合SUM()
函数,并查看带有连接操作的查询返回的详细信息行。
SELECT c.id AS `c.id`
, c.cost AS `c.cost`
, c.name AS `c.name`
, p.pid AS `p.pid`
, p.amount AS `p.amount`
, p.costid AS `p.costid`
FROM `Cost Table` c
LEFT
JOIN `Payment Table` p
ON p.costid = c.id
ORDER BY c.id, p.pid
这将返回:
c.id | c.cost | c.name | p.pid | p.amount | p.costid
1 | 100 | A | 1 | 10 | 1
1 | 100 | A | 2 | 20 | 1
1 | 100 | A | 4 | 50 | 1
2 | 200 | B | 3 | 30 | 2
3 | 200 | A | NULL | NULL | NULL
请注意,我们从Cost Table
中获得了 id=1 行的三个副本。
因此,如果我们修改该查询,添加GROUP BY c.name
并将 c.cost 包装在 SUM() 聚合中,我们将获得总cost
的膨胀值。
为避免这种情况,我们可以汇总Payment Table
的amount
,因此每个costid
只能获得一行。 然后,当我们执行连接操作时,我们不会从Cost
生成行的重复副本。
下面就来汇总从总量查询Payment Table
,所以我们得到每一个单列costid
。
SELECT p.costid
, SUM(p.amount) AS tot_amount
FROM `Payment Table` p
GROUP BY p.costid
ORDER BY p.costid
那将返回:
costid | tot_amount
1 | 80
2 | 30
通过使该查询成为“内联视图”,我们可以像使用表一样使用该查询的结果。 在这个例子中,我们为查询结果分配了一个别名v
。 (在 MySQL 中,“内联视图”称为“派生表”。)
SELECT c.name AS `name`
, SUM(c.cost) AS `sum_cost`
, IFNULL(SUM(v.tot_amount),0) AS `sum_amount`
FROM `Cost Table` c
LEFT
JOIN ( -- inline view to return total amount by costid
SELECT p.costid
, SUM(p.amount) AS tot_amount
FROM `Payment Table` p
GROUP BY p.costid
ORDER BY p.costid
) v
ON v.costid = c.id
GROUP BY c.name
ORDER BY c.name
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.