【问题标题】:Mysql re-using sums of subqueriesMysql重用子查询的总和
【发布时间】:2016-08-04 10:59:41
【问题描述】:

我有以下简化查询:

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;

我的愿望是重复使用 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;

当然我可以执行以下查询,但这会不必要地加倍运行时间:

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;

甚至将 sum1 和 sum2 结果插入到临时表中,但无法成像我忽略了一些东西,让 mysql 对求和字段进行一些有效的查询。

有没有更好、更有效的方法来重用求和字段?

【问题讨论】:

    标签: mysql subquery field


    【解决方案1】:

    尝试运行此查询,

    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
    )
    

    希望它会有所帮助。

    【讨论】:

      【解决方案2】:

      我的愿望是重复使用 sum1 和 sum2 而无需再次计算

      哇,稳住。原始查询的效率不如预期。在不知道数据分布是什么样子的情况下,很难建议最合适的查询是什么,但假设 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
      

      会更有效率。 (这也假设 ONLY_FULL_GROUP_BY 被禁用 - 否则您需要将 SELECT 子句中的 't.*' 和 group by 子句中的 't.id' 替换为您需要的表中的每个属性)。

      请注意,实际上您很少会在单个查询中查看所有您的数据。由于 MySQL 不能很好地处理推送谓词,因此简单地在外部 SELECT 中添加过滤器可能不是最佳解决方案。

      按照上述方式构建查询后,添加总和就很简单了:

      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
      

      (但请注意,我对您的数据和架构做了很多假设)

      【讨论】:

        猜你喜欢
        • 2011-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-03
        相关资源
        最近更新 更多