MySQL:子查询中的Sum值

时间:2010-08-18 18:09:38

标签: sql mysql subquery sum

我有关于学校体育的信息,包括学校,季节,现金流和cashflow_group的表格。我正在尝试在用户指定范围内的一个或多个给定cashflow_group中查询所有具有现金流量的学校。我需要在同一个查询中查询多个不同的类别。我遇到了麻烦。

我的查询如下。我这样做的原因是我可以汇总多个现金流量组,我认为它有效,直到我仔细观察并看到它将所有学校的现金流量总和为total_cashflow_amount,当每个学校应该具有不同的总和,关联的现金流行的总和。

SELECT distinct schools.*, 
  (SELECT sum(`cashflows`.amount) AS cf FROM `schools` 
  INNER JOIN `seasons` ON seasons.school_id = schools.id 
  INNER JOIN `cashflows` ON cashflows.season_id = seasons.id 
  INNER JOIN `cashflow_groups` ON `cashflow_groups`.id = `cashflows`.cashflow_group_id 
  WHERE ((`cashflow_groups`.id = 12) AND (`seasons`.`year` = 2010))) AS total_branding_cashflow 
FROM `schools` 

INNER JOIN `seasons` ON seasons.school_id = schools.id 
INNER JOIN `cashflows` ON cashflows.season_id = seasons.id 
INNER JOIN `cashflow_groups` ON `cashflow_groups`.id = `cashflows`.cashflow_group_id 
INNER JOIN `seasons` seasons_schools ON seasons_schools.school_id = schools.id 
WHERE (`seasons`.`year` = 2010) 
GROUP BY schools.id 
HAVING (total_branding_cashflow BETWEEN 50000000 AND 100000000) 
ORDER BY schools.name ASC LIMIT 0, 50

在此查询中,total_branding_cashflow所有学校的总数。我无法弄清楚如何在子查询中单独获得每所学校的总数。

目前,我得到的结果如

| school.id | … | total_branding_cashflow |
|     2     |   |       900000            |
|     5     |   |       900000            |

当我想要的是

| school.id | … | total_branding_cashflow |
|     2     |   |       500000            |
|     5     |   |       400000            |

在子查询中添加GROUP BY可以得到每个学校现金流在一个单独行中的总和,但子查询仅在它们给出一行时才起作用,所以这对我没有帮助。

我错过了什么?我之所以使用子查询,是因为我希望能够同时查找多个不同的cashflow_groups,如下所示:

SELECT distinct schools.*, 
  (SELECT sum(`cashflows`.amount) AS cf FROM `schools` 
  INNER JOIN `seasons` ON seasons.school_id = schools.id 
  INNER JOIN `cashflows` ON cashflows.season_id = seasons.id 
  INNER JOIN `cashflow_groups` ON `cashflow_groups`.id = `cashflows`.cashflow_group_id 
WHERE ((`cashflow_groups`.id = 12) AND (`seasons`.`year` = 2010)) ) AS total_branding_cashflow, 
  (SELECT sum(`cashflows`.amount) AS cf FROM `schools` 
  INNER JOIN `seasons` ON seasons.school_id = schools.id 
  INNER JOIN `cashflows` ON cashflows.season_id = seasons.id 
  INNER JOIN `cashflow_groups` ON `cashflow_groups`.id = `cashflows`.cashflow_group_id 
WHERE ((`cashflow_groups`.id = 1) AND (`seasons`.`year` = 2010)) ) AS total_ticket_sales_cashflow,
  (SELECT sum(`cashflows`.amount) AS cf FROM `schools` 
  INNER JOIN `seasons` ON seasons.school_id = schools.id 
  INNER JOIN `cashflows` ON cashflows.season_id = seasons.id 
  INNER JOIN `cashflow_groups` ON `cashflow_groups`.id = `cashflows`.cashflow_group_id 
WHERE ((`cashflow_groups`.id = 7) AND (`seasons`.`year` = 2010)) ) AS total_university_cashflow 
FROM `schools` 
INNER JOIN `seasons` ON seasons.school_id = schools.id 
INNER JOIN `cashflows` ON cashflows.season_id = seasons.id 
INNER JOIN `cashflow_groups` ON `cashflow_groups`.id = `cashflows`.cashflow_group_id 
INNER JOIN `seasons` seasons_schools ON seasons_schools.school_id = schools.id 
WHERE (`seasons`.`year` = 2010) 
GROUP BY schools.id 
HAVING (total_branding_cashflow BETWEEN 50000000 AND 100000000) AND 
       (total_ticket_sales_cashflow BETWEEN 50000000 AND 100000000) AND 
       (total_university_cashflow BETWEEN 0 AND 10000000) 
ORDER BY schools.name ASC LIMIT 0, 50

我不认为我可以使用不在其子查询中的SUM来执行此操作。我正在开发一个rails应用程序,并且可能想出一种通过ruby代码执行此操作的方法。但这似乎并不正确,如果可能的话,我更愿意在SQL中删除它。谢谢!

1 个答案:

答案 0 :(得分:3)

一些建议:

  • 加入seasons一次。连接会导致左表中的行重复,因此sum聚合可以将它们相加两次。如有疑问,请在没有group by的情况下为示例学校运行查询。
  • 您必须使用类似inner_schools.id = outer_schools.id
  • 的内容将子查询与外部查询相关联
  • 但据我所知,你根本不需要子查询

例如:

SELECT  schools.*
,       sum(cashflows.amount) total_branding_cashflow
FROM    schools
JOIN    seasons
ON      seasons.school_id = schools.id 
        and seasons.year = 2010
JOIN    cashflows
ON      cashflows.season_id = seasons.id 
        and cashflow_group_id = 12
GROUP BY 
        schools.id 
HAVING  total_branding_cashflow BETWEEN 50000000 AND 100000000

对于多个类别,您可以使用案例:

SELECT  schools.*
,       sum(case when cashflow_group_id = 1 then cashflows.amount end) total1
,       sum(case when cashflow_group_id = 12 then cashflows.amount end) total12
FROM    schools
JOIN    seasons
ON      seasons.school_id = schools.id 
        and seasons.year = 2010
JOIN    cashflows
ON      cashflows.season_id = seasons.id 
GROUP BY 
        schools.id