2016-11-11 37 views
0

我正在蜂巢中的桌子上工作,数十亿行和超过一百列。合并大量列

我需要合并100列中的第一个非零值。我能够做到这一点,但它涉及许多代码行(每列一行)。我还必须创建另一列,以相同的方式查找最后一个非零值,这意味着至少有另一个值。每列具有相同的命名约定,以便balance0,balance1,balance2等。

我想知道如果使用较少的代码行有更好的方法?我搜索了网页,可以找到很多关于凝聚价值的信息,但我似乎找不到任何有助于削减所需编码行数的内容。

我正在使用的代码的简化版本低于:

SELECT urn 
     ,COALESCE(IF(balance0  <> '0', balance0, NULL)  
       ,IF(balance1  <> '0', balance1, NULL)  
       ,IF(balance2  <> '0', balance2, NULL)  
       ,IF(balance3  <> '0', balance3, NULL)  
       ,IF(balance4  <> '0', balance4, NULL)  
       ,IF(balance5  <> '0', balance5, NULL)  
       ,IF(balance6  <> '0', balance6, NULL)  
       ,IF(balance7  <> '0', balance7, NULL)  
       ,IF(balance8  <> '0', balance8, NULL)  
       ,IF(balance9  <> '0', balance9, NULL)  
       ,IF(balance10 <> '0', balance10, NULL)  
       ,IF(balance11 <> '0', balance11, NULL)  
       ,IF(balance12 <> '0', balance12, NULL)  
       ,IF(balance13 <> '0', balance13, NULL)  
       ,IF(balance14 <> '0', balance14, NULL)  
       ,IF(balance15 <> '0', balance15, NULL)  
       ,IF(balance16 <> '0', balance16, NULL)  
       ,IF(balance17 <> '0', balance17, NULL)  
       ,IF(balance18 <> '0', balance18, NULL)  
       ,IF(balance19 <> '0', balance19, NULL)  
       ,IF(balance20 <> '0', balance20, NULL)  
       ,IF(balanceX.... etc to balance100 
       )  
       AS first_positive_balance 
FROM  table_x;  

非常感谢你提前为任何帮助!

+0

如果您需要这样做,那么您的数据库几乎肯定会布置得很差。您的余额应该存储在自己的表格中。 – meagar

+0

@meagar。是的,我同意这不是最好的布局。实际上,在真正的表格中,每个平衡都包含在单个列中的data_struct的元素中。如果我在列的上下文中而不是数据结构的元素中提问,我只是认为这个问题与更多人有关。我不知道它为什么按照它的方式进行布局,但你是对的,它当然可以做得更好。我相信这些数据在加载到Hadoop之前最初来自传统的大型机系统。 – data101

回答

0

对于你在问题中描述的情况,我没有看到很多快捷方式。 你可以编写一个自定义UDF(genericUDF),它可以处理任意数量的参数,但是你仍然必须指定全部调用UDF时的列。

对于注释中的情况(合并结构的许多元素),您可以编写一个只接收结构作为参数的自定义UDF。 hive结构实际上表示为Object [],所以无论有多少个结构元素,都可以很容易地实现任何函数。

Here's an example接收结构列表作为参数的genericUDF。

+0

L谢谢你的回复。我从来没有去过UDF,但愿意放弃它。这真的会为我节省大量的代码行,所以谢谢! – data101