将子查询转换为单个查询 Hive

Posted

技术标签:

【中文标题】将子查询转换为单个查询 Hive【英文标题】:Converting Sub query to a single query Hive 【发布时间】:2014-08-28 10:01:08 【问题描述】:

我有一个查询,它需要按 colB 分组的 colA 计数,并具有特定的 COlC 平均值平均值。例如

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,因此没有更多的中间数据大洗牌并且它在单个阶段运行?

【问题讨论】:

【参考方案1】:

我没有看到简化查询的简单方法。但是,将 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 值有一行的摘要就足够了。

【讨论】:

以上是关于将子查询转换为单个查询 Hive的主要内容,如果未能解决你的问题,请参考以下文章

将子选择 sql 查询转换为 laravel 查询

如何将子查询转换为连接以获得快速结果?

帮助将子查询转换为带连接的查询

postgres 将子字符串转换为纪元

将子查询(不在)重写为加入

将子查询的结果聚合为逗号分隔值