我有关于学校体育的信息,包括学校,季节,现金流和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中删除它。谢谢!
答案 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