我有两个表,一个是成本表,另一个是付款表,成本表包含产品名称的产品成本。
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
如果有人能帮助我解决问题或者更好地了解如何解决问题,我将不胜感激。谢谢
答案 0 :(得分:1)
这应该有效:
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
答案 1 :(得分:1)
您需要在分开的查询中进行计算,然后将它们连接在一起。
name
cost_id
<强> SQL Fiddle Demo 强>
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 |
答案 2 :(得分:0)
有几个问题。首先,列引用应该是限定的,而不是聚合函数。
这是无效的:
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
,其中GROUP BY
不 UNIQUE,您就有可能生成(部分)笛卡尔积。< / p>
要查看其外观,看看发生了什么,请删除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
请注意,我们正在从GROUP BY c.name
获取id = 1行的三个副本。
因此,如果我们修改了该查询,添加了cost
,并将c.cost包装在SUM()聚合中,那么我们将获得总amount
的夸大值。
为避免这种情况,我们可以汇总Payment Table
中的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
我们可以使用该查询的结果,就像它是一个表一样,通过使该查询成为&#34;内联视图&#34;。在此示例中,我们为查询结果指定了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
的别名。 (在MySQL版本中,&#34;内联视图&#34;被称为&#34;派生表&#34;。)
@using (Ajax.BeginForm("SignUpForFree", null, new AjaxOptions()
{
InsertionMode = InsertionMode.Replace
}, new { id = "signup-form" }))
{
@Html.LabelFor(m => m.Email)
@Html.TextBoxFor(m => m.Email)
<input type="submit" value="CREATE FREE ACCOUNT" onclick="customSubmit()"/>
}