从sql中的两个表汇总列

时间:2016-10-05 15:38:26

标签: mysql 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

如果有人能帮助我解决问题或者更好地了解如何解决问题,我将不胜感激。谢谢

3 个答案:

答案 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

SQLFiddle

答案 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()"/>
    }