我正在Hive中处理一个有几十亿行和一百多列的表。
我需要合并100列中的第一个非零值。我能够做到这一点,但它涉及许多行代码(每列一行)。我还必须创建另一个列,它以相反的方式执行相同的操作,以找到最后一个非零值,这意味着至少还有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;
非常感谢您的帮助!
1条答案
按热度按时间jbose2ul1#
对于你在问题中描述的情况,我看不到很多捷径。。您可以编写一个自定义udf(genericudf),它可以处理任意数量的参数,但在调用udf时仍然必须指定所有列。
对于注解中的情况(合并一个结构的许多元素),您可以编写一个只接收该结构作为参数的自定义udf。hive struct实际上表示为object[],因此无论struct元素有多少,都可以很容易地在struct元素上实现任何函数。
下面是一个将结构列表作为参数接收的genericudf示例。