2016-11-11 4 views
0

Я работаю над столом в улье с несколькими миллиардами строк и более ста столбцов.Coalesce на огромном количестве столбцов

Мне нужно объединить первое ненулевое значение из 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;  

Большое спасибо заранее за любую помощь!

+0

Ваша база данных почти наверняка выложена плохо, если вам нужно это сделать. Ваши балансы, вероятно, должны храниться в их собственной таблице. – meagar

+0

@meagar. Да, я согласен, что это не лучший план. Фактически, в реальной таблице каждый из этих балансов содержится в элементе data_struct в одном столбце. Я просто подумал, что вопрос будет уместен для большего количества людей, если бы я спросил его в контексте столбцов, а не в элементах структуры данных. Я не уверен, почему это изложено так, как есть, но вы правы, это, безусловно, может быть сделано лучше. Я полагаю, что данные изначально были получены из старой системы мэйнфреймов, прежде чем она была загружена на Hadoop. – data101

ответ

0

Для случая, который вы описываете в вопросе, я не вижу много ярлыков. Вы можете написать пользовательский UDF (genericUDF), который мог бы работать с любым количеством аргументов, но вам все равно придется указывать все столбцы при вызове UDF.

Для случая в комментарии (объединить многие элементы структуры) вы можете написать пользовательский UDF, который получает только конструкцию в качестве параметра. Структура hive фактически представлена ​​как Object [], поэтому было бы легко реализовать любую функцию на элементах структуры независимо от того, сколько их там.

Here's an example genericUDF, который получает список структур как параметр.

+0

L спасибо за этот ответ. Я никогда не ездил в UDF, но хотел бы, чтобы он пошел. Это действительно избавит меня от огромного количества строк кода, поэтому спасибо! – data101