Hive: использование Concat в имени столбца - PullRequest
1 голос
/ 23 апреля 2019

Я пытаюсь получить данные из таблицы с именем столбца: year_2016, year_2017, year_2018 и т. Д. Я не уверен, как получить данные из этой таблицы.Данные выглядят так:

| count_of_accidents | year_2016 | year_2017 |year_2018 | 
|--------------------|-----------|-----------|----------|
| 15                 | 12        | 5         | 1        |
| 5                  | 10        | 6         | 18       |

Я пробовал использовать функцию concat, но на самом деле это не работает.

Я пытался с этим:

select SUM( count_of_accidents * concat('year_',year(regexp_replace('2018_1_1','_','-')))) 
from table_name;

Имя столбца (год_2017 или год_2018 и т. Д.) Будет передан в качестве параметра.Поэтому я не могу жестко закодировать имя столбца следующим образом:

select SUM( count_of_accidents * year_2018) from table_name;

Есть ли способ сделать это?

1 Ответ

4 голосов
/ 23 апреля 2019

Вы можете сделать это, используя регулярные выражения .Например:

--create test table
create table test_col(year_2018 string, year_2019 string);

set hive.support.quoted.identifiers=none;
set hive.cli.print.header=true;

--test select using hard-coded pattern
select year_2018, `(year_)2019` from test_col;
OK
year_2018       year_2019
Time taken: 0.862 seconds

--test pattern parameter
set hivevar:year_param=2019;

select year_2018, `(year_)${year_param}` from test_col;
OK
year_2018       year_2019
Time taken: 0.945 seconds

--two parameters
set hivevar:year_param1=2018;
set hivevar:year_param2=2019;

select `(year_)${year_param1}`, `(year_)${year_param2}`  from test_col t;
OK
year_2018       year_2019
Time taken: 0.159 seconds

--parameter contains full column_name and using more strict regexp pattern
set hivevar:year_param2=year_2019;

select `^${year_param2}$` from test_col t;
OK
year_2019
Time taken: 0.053 seconds

--select all columns using single pattern year_ and four digits
select `^year_[0-9]{4}$`  from test_col t;
OK
year_2018       year_2019

Параметр должен быть рассчитан и передан в скрипт куста, никакие функции, такие как concat (), regexp_replace, не поддерживаются в именах столбцов.

Также псевдоним столбца не работает для столбцов, извлеченных с использованием регулярных выражений:

 select t.number_of_incidents, `^${year_param}$` as year1 from test_t t;

выдает исключение:

FAILED: SemanticException [Ошибка 10004]: строка 1: 30 Недопустимый псевдоним таблицы или ссылка на столбец '^year_2018$': (возможные имена столбцов: number_of_incidents, year_2016, year_2017, year_2018)

Я нашел обходной путь для псевдонима столбца, используя объединение с пустымнабор данных, см. этот тест:

create table test_t(number_of_incidents int, year_2016 int, year_2017 int, year_2018 int);
insert into table test_t values(15, 12, 5, 1); --insert test data
insert into table test_t values(5,10,6,18);

--parameter, can be passed from outside the script from command line  
set hivevar:year_param=year_2018;

--enable regex columns and print column names
set hive.support.quoted.identifiers=none;
set hive.cli.print.header=true;

--Alias column using UNION ALL with empty dataset
select sum(number_of_incidents*year1) incidents_year1 
  from
    (--UNION ALL with empty dataset to alias columns extracted
     select 0 number_of_incidents, 0 year1 where false --returns no rows because of false condition
     union all
     select t.number_of_incidents, `^${year_param}$` from test_t t
    )s;

Результат:

OK
incidents_year1
105
Time taken: 38.003 seconds, Fetched: 1 row(s)

Первый запрос в UNION ALL не влияет на данные, поскольку не возвращает строк.Но имена столбцов становятся именами всего набора данных UNION ALL и могут использоваться в верхнем запросе.Этот трюк работает.Если вы найдете лучший обходной путь к столбцам псевдонимов, извлеченным с помощью регулярных выражений, добавьте также свое решение.

Обновление:

Нет необходимости в регулярных выражениях, если вы можете передатьполное имя столбца в качестве параметра.Hive заменяет переменные как есть (не вычисляет их) перед выполнением запроса.Используйте regexp, только если по какой-то причине вы не можете передать полное имя столбца, и, как и в исходном запросе, необходима конкатенация некоторых шаблонов.Смотрите этот тест:

--parameter, can be passed from outside the script from command line  
set hivevar:year_param=year_2018;

select sum(number_of_incidents*${year_param}) incidents_year1 from test_t t;

Результат:

OK
incidents_year1
105
Time taken: 63.339 seconds, Fetched: 1 row(s)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...