将子查询转换为单个查询配置单元

zynd9foi  于 2021-05-30  发布在  Hadoop
关注(0)|答案(1)|浏览(273)

我有一个查询,它需要一个colc值的特殊平均值colb分组计数。例如

SELECT COUNT( X.colA ), X.colB , X.MEASURE
FROM (
  SELECT colA  , colB  , avg(colC) MEASURE
  FROM tableA
  GROUP BY colA, colB
  HAVING round(avg(colC),2) > 0
) X 
GROUP BY X.MEASURE , X.colB
HAVING X.MEASURE BETWEEN 0 AND 3000
ORDER BY MEASURE

示例结果可能是

No of User, URL    , average time spent
90182     , abc.com,    334
293556    , def.com,     33

上述查询的问题是,由于它有一个子查询,内部子查询将大量数据作为中间结果洗牌到外部查询,这导致在大型数据集上的查询变得非常慢。
有没有一种方法可以将上面的查询转换成没有任何子查询的查询,或者有没有任何udaf可用,这样中间数据就不会出现更大的混乱,而是在一个阶段中运行?

xzabzqsa

xzabzqsa1#

我不认为有什么简单的方法可以简化查询。但是,移动 having 子查询中的子句可能有助于提高性能:

SELECT COUNT( X.colA ), X.colB , X.MEASURE
FROM (SELECT colA  , colB  , avg(colC) MEASURE
      FROM tableA
      GROUP BY colA, colB
      HAVING round(avg(colC),2) > 0 and avg(colC) <= 3000
     ) X 
GROUP BY X.MEASURE , X.colB
ORDER BY MEASURE;

您希望按一组行的平均值进行聚合。这似乎需要两个操作——一个用于计算平均值,另一个用于最终聚合。
实际上,如果我仔细想想,下面这些可能会满足您的要求:

select colB, count(distinct colA), sum(colC) / count(distinct colA) as measure
from tableA
group by colA
having sum(colC) / count(distinct colA) between 0 and 3000
order by measure;

这不完全一样,但我不明白分组的目的 measure 在外部查询中。一行一行的摘要 b 价值就足够了。

相关问题