蜂巢:列名称中Concat的用法

时间:2019-04-22 21:06:59

标签: hive hiveql

我正在尝试从具有列名称为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;

列名(year_2017或year_2018等)将作为参数传递。所以,我真的不能像这样硬编码列名-

select SUM( count_of_accidents * year_2018) from table_name;

有什么办法可以做到这一点?

1 个答案:

答案 0 :(得分:4)

您可以使用regular expressions进行操作。像这样:

cshtml

应该计算参数并将其传递给hive脚本,列名中不支持诸如concat(),regexp_replace之类的函数。

列别名也不适用于使用正则表达式提取的列:

--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

引发异常:

  

失败:SemanticException [错误10004]:行1:30无效的表别名   或列引用“ select t.number_of_incidents, `^${year_param}$` as year1 from test_t t; ” :(可能的列名称为:   事件数,年份2016,年份2017,年份2018)

我找到了一种解决方法,可以使用带有空数据集的并集对列进行别名,请参见此测试:

^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数据集的名称,并且可以在上层查询中使用。这个技巧有效。如果您发现使用regexp提取列的别名的更好解决方法,请同时添加解决方案。

更新

如果可以传递完整的column_name作为参数,则不需要正则表达式。 Hive在执行查询之前按原样替换变量(不计算变量)。仅当由于某些原因而无法传递完整的列名,并且像在原始查询中那样需要某些模式串联时,才使用regexp。查看此测试:

UNION ALL

结果:

--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;