简体   繁体   English

MySQL重用子查询的总和

[英]Mysql re-using sums of subqueries

I have the following simplified query: 我有以下简化的查询:

Select
(select sum(f1) from tableA a where a.id = t.id) sum1,
(select sum(f2) from tableB b where b.id = t.id) sum2,
t.*
from Table t;

My wish is to have sum1 and sum2 re-used without calculating them again: 我希望重新使用sum1和sum2而不重新计算它们:

Select
(select sum(f1) from tableA a where a.id = t.id) sum1,
(select sum(f2) from tableB b where b.id = t.id) sum2,
sum1 + sum2 `sum3`,    
t.*
from Table t;

Of course i can do the following query but this will unnecessary double the run time: 当然,我可以执行以下查询,但这将不必要地使运行时间加倍:

Select
(select sum(f1) from tableA a where a.id = t.id) sum1,
(select sum(f2) from tableB b where b.id = t.id) sum2,
(select sum(f1) from tableA a where a.id = t.id) + 
(select sum(f2) from tableB b where b.id = t.id) `sum3`,    
t.*
from Table t;

or even inserting the sum1 and sum2 results to a temporary table but can't imaging i'm overlooking something to have mysql do some efficient querying on summed fields. 甚至将sum1和sum2结果插入到临时表中,但无法想象我正在忽略使mysql对求和字段进行一些有效查询的方法。

Is there a better, more efficient way to re-use summed fields? 有没有更好,更有效的方法来重用求和字段?

Try running this query, 尝试运行此查询,

select Resutl.*,Result.sum1+Result.sum2 as sum3 from(
       SELECT (SELECT SUM(f1) FROM tableA a WHERE a.id = t.id) sum1,
              (SELECT SUM(f2) FROM tableB b WHERE b.id = t.id) sum2,
              t.*
       FROM Table t)Result
)

Hope it will help. 希望它会有所帮助。

My wish is to have sum1 and sum2 re-used without calculating them again 我的愿望是重新使用sum1和sum2而不重新计算它们

Whoa, steady on. 哇,坚持下去。 The original query is not as efficient as it might be. 原始查询效率不如预期。 Without knowing what the data distribution looks like its hard to advise what the most appropriate query is, but assuming that the tuples in A and B have a foreign key constraint (implicit or explicit) on table T but no implicit foreign key restraint on each other, that t.id is unique, and most of the rows in tableT have corresponding rows in tableA and tableB then.... 在不知道数据分布是什么样的情况下,很难建议最合适的查询是什么,而是假设A和B中的元组在表T上具有外键约束(隐式或显式),而彼此之间没有隐式外键约束,则t.id是唯一的,然后tableT中的大多数行在tableA和tableB中都有对应的行。

SELECT t.*, sum_f1, sum_f2
FROM tableT t
LEFT JOIN (SELECT a.id, SUM(f1) AS sum_f1
 FROM tableA a
 GROUP BY a.id) AS a_agg
ON t.id=a_agg.id
LEFT JOIN (SELECT b.id, SUM(f2) AS sum_f2
 FROM tableB b
 GROUP BY b.id) as b_agg
ON t.id=b_agg.id
GROUP BY t.id

Will be much more efficient. 效率会大大提高。 (this also assumes that ONLY_FULL_GROUP_BY is disabled - otherwise you'll need to replace 't.*' in the SELECT clause and 't.id' in the group by clause with each of the attributes you need from the table). (这也假定禁用了ONLY_FULL_GROUP_BY-否则,您将需要用表中的每个属性替换SELECT子句中的“ t。*”和group by子句中的“ t.id”)。

Note that in practice you're rarely going to be looking at all your data in a single query. 请注意,实际上,您很少会在单个查询中查看所有数据。 Since MySQL doesn't handle push predicates very well, simply adding a filter in the outer SELECT probably won't be the optimal solution. 由于MySQL无法很好地处理推式谓词,因此仅在外部SELECT中添加过滤器可能不是最佳解决方案。

Once you've structured your query as above, it's trivial to add the sums: 一旦按照上述方法构建了查询,添加总和就很简单了:

SELECT t.*, sum_f1, sum_f2, 
 IFNULL(sum_f1,0)+INFULL(sum_f2,0) AS sum3
FROM tableT t
LEFT JOIN (SELECT a.id, SUM(f1) AS sum_f1
 FROM tableA a
 GROUP BY a.id) AS a_agg
ON t.id=a_agg.id
LEFT JOIN (SELECT b.id, SUM(f2) AS sum_f2
 FROM tableB b
 GROUP BY b.id) as b_agg
ON t.id=b_agg.id
GROUP BY t.id

(but note that I've made a lot of assumptions about your data and schema) (但是请注意,我对您的数据和架构做了很多假设)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM