我有有关学校体育运动的信息,其中包含学校、季节、现金流和 cashflow_group 的表格。我正在尝试查询在用户指定范围内的一个或多个给定 cashflow_groups 中拥有现金流的所有学校。我需要在同一个查询中查询多个不同的类别。我遇到了麻烦。
我的查询如下。我这样做的原因是我可以对多个现金流组进行求和,我认为它有效,直到我仔细观察并发现它将所有学校的现金流量求和为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 来记录它。谢谢!
最佳答案
一些建议:
- 加入
季节
一次。连接会导致左表中的行重复,因此可以通过sum
聚合将它们求和两次。如有疑问,请针对示例学校运行不带group by
的查询。 - 您必须使用
inner_schools.id = external_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
关于sql - MySQL:子查询中的总和值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3515193/