#sql #hadoop #hive #user-defined-functions
#sql #hadoop #улей #определяемые пользователем-функции
Вопрос:
У меня есть таблица в улье, структурированная из 3 столбцов следующим образом;
timestamp UserID OtherId
2016-09-01 123 "101","222","321","987","393.1","090","467","863"
2016-09-01 124 "188","389","673","972","193","100","143","210"
2016-09-01 125 "888","120","482","594","393.2"
2016-09-01 126 "441","501","322","671","008","899"
2016-09-01 127 "004","700","393.4","761","467","356","643","578"
2016-09-01 128 "322","582","348"
2016-09-01 129 "029","393.8","126","187"
Где OtherID — это массив.
Мне нужно проанализировать OtherID, чтобы результирующий набор данных был следующим, поскольку меня интересуют только значения, которые содержат ‘393%’
timestamp UserID OtherId
2016-09-01 123 393.1
2016-09-01 125 393.2
2016-09-01 127 393.4
2016-09-01 129 393.8
Я исследовал множество функций синтаксического анализа, но, похоже, все они предназначены для возврата позиции значения, или вам нужно указать позицию значения, чтобы вернуть его. Обе эти опции здесь не работают, потому что ‘3309%’ может встречаться в любой точке массива для любой заданной строки.
Существует также тот факт, что мне нужно включить подстановочный знак, чтобы разрешить варианты желаемого значения.
Другой вариант — explode, но моя таблица просто слишком велика для этой опции.
Я думаю, что UDF может быть единственным способом, но я бы приветствовал некоторые рекомендации там.
Благодарен за любую помощь.
Комментарии:
1. Не могли бы вы попробовать что-то подобное?
SELECT * FROM table WHERE OtherId RLIKE regexp_extract(OtherId, '("393.d")', 1)
2. Спасибо за предложение. Выдает следующую ошибку: «Ошибка при компиляции инструкции: СБОЙ: SemanticException [Ошибка 10014]: Строка 2: 19 неверных аргументов «(«393 . d «)»: Нет метода сопоставления для класса org.apache.hadoop.hive.ql.udf.udfreg expextract с (array<строка>, строка). Возможные варианты: _FUNC_(строка, строка) _FUNC_(строка, строка, int)»
3. Хорошо, я не понял, что OtherId — это массив, а не строка. Возможно, у Hive есть собственная функция, которая могла бы каким-то образом «объединить» элементы массива, чтобы вы могли использовать регулярное выражение…
4. Подождите, это будет работать только со строкой? Вы видите, что OtherID был строкой до того, как я использовал функцию для преобразования ее в массив, потому что я предполагал, что это упростит обработку. Должен ли я вместо этого применить ваше предложение регулярного выражения к строке?
5. Да, пожалуйста, попробуйте использовать вместо этого строку. Как числа разделяются внутри строки? Разделены ли они запятыми? нравится
"101,222,321"
или у них есть пробелы между ними? В зависимости от этого мне нужно немного изменить регулярное выражение
Ответ №1:
Легко сделать то, что вам нужно, используя опцию бокового обзора, доступную в hive.
0: jdbc:hive2://quickstart:10000/default> select * from test_5;
----------- ------------ ----------------------------------------------
| test_5.t | test_5.id | test_5.oid |
----------- ------------ ----------------------------------------------
| 123 | 123 | "222","321","987","393.1","090","467","863" |
----------- ------------ ----------------------------------------------
И в этом весь фокус:
SELECT id, ooid
FROM test_5
LATERAL VIEW EXPLODE(SPLIT(oid,",")) temp AS ooid;
------ ----------
| id | ooid |
------ ----------
| 123 | "222" |
| 123 | "321" |
| 123 | "987" |
| 123 | "393.1" |
| 123 | "090" |
| 123 | "467" |
| 123 | "863" |
------ ----------
Следовательно:
SELECT id, regexp_replace(ooid,'"','')
FROM test_5
LATERAL VIEW EXPLODE(SPLIT(oid,",")) temp AS ooid;
WHERE ooid LIKE '"393%';
------ ----------
| id | ooid |
------ ----------
| 123 | 393.1 |
------ ----------
Ответ №2:
Может быть, вы можете попробовать, как показано ниже:
hive> select timestamp1, userid, otherids from userdet1 LATERAL VIEW explode(otherid) testTable as otherids where otherids LIKE concat('393','%');
ОК
2016-09-01 123 393.1
2016-09-01 125 393.2
2016-09-01 127 393.4
2016-09-01 129 393.8
Time taken: 0.297 seconds, Fetched: 4 row(s)