Операции с массивами (добавление массивов) в улье
У меня есть таблица hive со столбцами id (String), val (String) как:
id,val
abc,{0|1|0}
abc,{0|1|1}
abc,{1|0|1|1}
Я хочу добавить столбец val, группирующий столбец id. Ожидаемый результат:
id,val
abc,{1|2|2|1}
Этот результат был бы получен путем параллельного добавления массивов.
Я попробовал с помощью бокового вида взорваться, а затем бросить как int и так далее. Но не в состоянии получить ожидаемый результат. Я знаю, что использование UDF также является вариантом, но есть ли какой-либо другой способ только в hive.
Любые предложения были бы полезный.
Спасибо
3 ответа:
Это один из возможных путей, могут быть и лучшие
select * from tbl1; +----------+------------+--+ | tbl1.id | tbl1.val | +----------+------------+--+ | abc | {0|1|0} | | abc | {0|1|1} | | abc | {1|0|1|1} | +----------+------------+--+
Напишите его где-нибудь без
{}
insert overwrite directory '/user/cloudera/tbl2' row format delimited fields terminated by ',' select id, substr(val,2,length(val)-2) as val2 from tbl1
Создайте таблицу, чтобы использовать ее
create external table tbl3(id string, val array<int>) row format delimited fields terminated by ',' collection items terminated by '|' location '/user/cloudera/tbl2' +----------+------------+--+ | tbl3.id | tbl3.val | +----------+------------+--+ | abc | [0,1,0] | | abc | [0,1,1] | | abc | [1,0,1,1] | +----------+------------+--+
Использовать
posexplode
select id, collect_list(val) from ( select id, sum(c) as val from ( select id, i, c from tbl3 lateral view posexplode(val) v1 as i, c ) tbl group by id, i ) tbl2 group by id
Результат
+------+------------+--+ | id | _c1 | +------+------------+--+ | abc | [1,2,2,1] | +------+------------+--+
Начните с замены
{
,}
с пробелами,split
строку и использоватьlateral view
сposexplode
для суммирования чисел в том же положении.select id,pos,sum(split_val) as total from lateral view posexplode(split(regexp_replace(val,'[{}]',''),'\\|')) tbl as pos,split_val group by id,pos
Затем используйте
collect_list
для создания конечного массива.select id,collect_list(total) from (select id,pos,sum(split_val) as total from lateral view posexplode(split(regexp_replace(val,'[{}]',''),'\\|')) tbl as pos,split_val group by id,pos ) t group by id
Таблица улья mytab:
+----------+------------+ | id | val | +----------+------------+ | abc | {0|1|0} | | abc | {0|1|1} | | abc | {1|0|1|1} | +----------+------------+
Ожидаемый результат:
+----------+------------+ | id | val | +----------+------------+ | abc | {1|2|2|1} | +----------+------------+
Используемый запрос Hive:
select id,concat('{',concat_ws('|',(collect_list(cast(cast(expl_val_sum as int)as string)))),'}') as coll_expl_val from( select id,index,sum(expl_val) as expl_val_sum from mytab lateral view posexplode(split(regexp_replace(val,'[{}]',''),'\\|')) exp as index,expl_val group by id,index)a group by id;
1.First posexplode is used which explodes the array[String]. 2.Then based on the index column the array values are added up parallelly. 3.Then cast as int is used to convert from decimal values to integer. 4.Then cast as String and then again converted to array[string] using collect_list. 5.Next the values of array are '|' delimited using concat_ws function. 6.Next concat function is used to append '{' and '}'.
Спасибо за все ваши ответы.