2014-08-18 4 views
1

Я использую функцию split для создания массива в Hive, как я могу получить первые n элементов из массива, и я хочу пройти через подматрицуКак получить первые n элементов в массиве в Hive

пример кода

select col1 from table 
where split(col2, ',')[0:5] 

'[0: 5] выглядит стиль любит питона, но он здесь не работает.

+0

, что именно вы собираетесь делать с п элементов? вы хотите, чтобы каждый элемент находился в отдельной строке или в отдельном столбце? – dimamah

+0

Я хочу, чтобы они были в отдельной строке, и я хочу, чтобы было статистическое отношение некоторого значения в первых n элементах. Предположим, у меня есть формат строки, такой как «abC# 1, def # 2, hij # 3» ... теперь, я хочу знать, каково соотношение №1 или №2 в первых трех элементах. –

+0

отправил его в качестве ответа .. – dimamah

ответ

-1

Это сложный вопрос.
Сначала возьмите Brickhouse банку с here
Тогда добавьте его в улье: add jar /path/to/jars/brickhouse-0.7.0-SNAPSHOT.jar;

Теперь создадим две функции мы будем usings:

CREATE TEMPORARY FUNCTION array_index AS 'brickhouse.udf.collect.ArrayIndexUDF';
CREATE TEMPORARY FUNCTION numeric_range AS 'brickhouse.udf.collect.NumericRange';

запрос будет:

select a, n as array_index, array_index(split(a,','),n) as value_from_Array from (select "abc#1,def#2,hij#3" a from dual union all select "abc#1,def#2,hij#3,zzz#4" a from dual) t1 lateral view numeric_range(length(a)-length(regexp_replace(a,',',''))+1) n1 as n

Разъяснения:
select "abc#1,def#2,hij#3" a from dual union all select "abc#1,def#2,hij#3,zzz#4" a from dual

ли просто выбрать некоторые тестовые данные, в вашем случае заменить это с вашим именем таблицы.

lateral view numeric_range(length(a)-length(regexp_replace(a,',',''))+1) n1 as n

numeric_range является UDTF, который возвращает таблицу для заданного диапазона, в данном случае, я просил диапазон от 0 (по умолчанию), а количество элементов в строке (рассчитываются как число запятых + 1)
Таким образом, каждая строка будет умножаться на количество элементов в данном столбце.

array_index(split(a,','),n)

Это так же, как с помощью split(a,',')[n] но улей не поддерживает его.
Таким образом, мы получаем п-й элемент для каждой повторяющейся строки исходной строки в результате:

abc#1,def#2,hij#3,zzz#4 0 abc#1 abc#1,def#2,hij#3,zzz#4 1 def#2 abc#1,def#2,hij#3,zzz#4 2 hij#3 abc#1,def#2,hij#3,zzz#4 3 zzz#4 abc#1,def#2,hij#3 0 abc#1 abc#1,def#2,hij#3 1 def#2 abc#1,def#2,hij#3 2 hij#3

Если вы действительно хотите определенное количество элементов (скажем, 5), а затем просто использовать:
lateral view numeric_range(5) n1 as n

1

Это гораздо более простой способ сделать это. Существует UDF here под названием TruncateArrayUDF.java, который может делать то, что вы просите. Просто клонируйте repo с главной страницы и постройте банку с помощью Maven.

Пример данных:

|  col1   | 
---------------------- 
    1,2,3,4,5,6,7 
    11,12,13,14,15,16,17 

Запрос:

add jar /complete/path/to/jar/brickhouse-0.7.0-SNAPSHOT.jar; 
create temporary function trunc as 'brickhouse.udf.collect.TruncateArrayUDF'; 

select pos 
     ,newcol 
from (
     select trunc(split(col1, '\\,'), 5) as p 
     from table 
    ) x 
lateral view posexplode(p) explodetable as pos, newcol 

Выход:

pos | newcol | 
------------------- 
    0   1 
    1   2 
    2   3 
    3   4 
    4   5 
    0   11 
    1   12 
    2   13 
    3   14 
    4   15 
+0

Да, то, что делает Dimamesh, будет технически работать, но «truncate_array» был специально создан для этого прецедента. Кирпичный дом можно найти по адресу http://github.com/klout/brickhouse. –

+0

@JeromeBanks Спасибо за все UDF. Я использую их каждый день. качественный товар. – gobrewers14

+1

Можете ли вы дать мне решение без использования UDF? –

Смежные вопросы