使用不同长度的行在Hive中加载CSV文件

时间:2014-05-22 15:56:24

标签: database database-design hadoop hive hiveql

如何在Hive中加载CSV文件,每行包含不同数量的列? 问题是每行都有一个未定义的字段数,否则我会创建一个表格,其中包含我的CSV可以拥有的最大字段数...

字段1到5将始终存在。但是,6到Infinity的字段可能并不总是存在。 可以接受的解决方案是在Hive中导入文件时将字段6连接到Infinity。

这甚至可能吗?

以下是我的CSV文件样本,以便明确:

data11;data12;data13;data14
data21;data22;data23;data24;data25
data31;data32;data33;data34;data35;data36
data41;data42;data43

2 个答案:

答案 0 :(得分:1)

我能想到的三个选择:

如果可能字段的数量不是真正无限但仅高于5,那么您可以简单地定义所有这些字段,而数据中不存在的字段将只为空。

你可以写一个自定义的SerDe。

或者您可以将分隔符设置为数据中不存在的内容,然后使用正则表达式自行提取字段。例如:

create table a(line string) row format delimited fields terminated by '\A';

create view b as
select
regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)', 1) as col1,
regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)', 2) as col2,
regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)', 3) as col3,
regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)', 4) as col4,
regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)', 5) as col5,
split(regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)', 6), '\;') as rest
from a;

答案 1 :(得分:0)

感谢您的回答,这对我非常有帮助。

我选择了我修改了一下的第三个选项,因为看起来6到Infinity的字段(当然不是真的无限)在最后一列中没有正确插入。实际上,只有字段6被插入到视图“b”中。

我在同一个字符串中将字段6连接到Infinity,但用管道字符“|”分隔。 这是修改后的代码:

create view b as
select
regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)', 1) as col1,
regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)', 2) as col2,
regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)', 3) as col3,
regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)', 4) as col4,
regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)', 5) as col5,
regexp_replace(regexp_extract(line, '([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;([^\;]*)\;(.*)', 6), '\;', '|') as rest
from a;