如何在Hive(HQL)查询中重用表达式?

时间:2014-09-30 22:18:55

标签: sql hive hql

我是Hive和SQL的新手,所以这可能是一个简单的问题,但我没有找到几小时网络搜索的解决方案。

我正在select查询中编写表达式,我希望在select查询的其他列中使用这些表达式。例如,

select (-b + sqrt(b*b - 4*a*c))/(2*a), (-b - sqrt(b*b - 4*a*c))/(2*a) from tablename;

除了重新计算判别式(sqrt(b*b - 4*a*c))的效率低下之外,这种事情很难被人类阅读。如果这是一个程序,我会像这样存储部分结果disc = sqrt(b*b - 4*a*c)

select [somehow assign disc] (-b + disc)/(2*a), (-b - disc)/(2*a) from tablename;

我在“临时变量”和“表变量”上找到的内容看起来像是一个单独的查询,它被保存到一个中间表并折叠到主查询中,这对于那些本应应该的东西来说是一个很大的开销。零开销。如果Hive想要,它可以在提交查询之前扩展我的所有表达式(尽管我更喜欢它实际上避免重新计算)。

我正在寻找的是什么名字?如何重写上面的示例只显示sqrt(b*b - 4*a*c)一次,只提交一个map-reduce作业(没有中间临时表)?

(我的实际情况更复杂,计算量更大。)

1 个答案:

答案 0 :(得分:1)

如果要点在每次使用光盘时都不重写整个代码,可以创建Hive UDF(用户自定义函数)。 我不确定函数结果是否被缓存/如果对具有相同参数的多个函数调用进行任何优化。

如果要计算" disc"的结果。只能按行一次,您可以使用common table expression

  

用q1作为(选择sqrt(b * b - 4 * a * c)作为光盘,a,b,c来自tablename)

     

从q1中选择(-b + disc)/(2 * a),( - b - disc)/(2 * a);

您也可以使用子查询

  

选择(-b + disc)/(2 * a),( - b - disc)/(2 * a)来自

     

(选择sqrt(b * b - 4 * a * c)作为光盘,a,b,c来自tablename)q1


更新:

我比较了3个查询的性能(选择重新计算,CTE和子查询),执行时间大致相同(18,91,18,78,18,94)。

Hive执行引擎似乎很聪明!

因此,您可能关心的唯一考虑因素是代码的可读性。 (除非你的测试,在一个更复杂的过程中显示,否则,我很高兴听到)