在 Hive 中处理带和不带双引号的数据
Posted
技术标签:
【中文标题】在 Hive 中处理带和不带双引号的数据【英文标题】:Handling Data with and Without double quotation marks In Hive 【发布时间】:2021-01-22 15:48:55 【问题描述】:有人可以指导我如何将数据加载到配置单元中,我得到“在某些行中,而在某些行中,数据没有”对于相同的列值。
Sample Data:
id,name,desc,uqc,roll,age
1,Monali,"abhc,jkjk",,23,23
2,mj,nhiijkla,67,23,60
7,jena,"kdjuu,hsysi,juw",3,34,23
1,Monali,"/"coppers bars","rods and profiles"/",,23,23
2,money,"/"COUPLING","FLANGES & CROSS OVER"/",67,23,60
id '2' 的上述数据“在 desc 列值中不存在。
我的创建声明:
create external table testing(id int,
name string,
desc string,
uqc double,
roll int,
age int
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES ('input.regex'='^(\\d+?),(.*?),"(.*)",([0-9.]*),([0-9]*),([0-9]*).*')
location ....
TBLPROPERTIES("skip.header.line.count"="1")
;
在加载数据时,我没有收到任何错误。但是当我执行 select * from testing.select 语句时不会执行。上面的创建和选择语句工作正常如果数据带有“,但如果数据带有和不带有”则不起作用。
【问题讨论】:
你能用openCSVSerde吗?CREATE EXTERNAL TABLE tab ( desc STRING, id BIGINT ) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH SERDEPROPERTIES ( "separatorChar" = ",", "quoteChar" = "\"") LOCATION '/your/dir/location/';
@KoushikRoy 我试过了,但如果是这一行:--> 2,money,"17",19"LCD PANEL FOR COMPUTER",67,23,60 它不起作用。 "17",19"LCD PANEL FOR COMPUTER" 是我的 desc 列值的值,但它在 desc 列中加载 17,在下一列中加载 19"LCD PANEL FOR COMPUTER。
你不觉得这不一致吗?你能把所有的列都用双引号括起来吗?这将确保良好的数据质量。如果它不可能,那么我不确定我们如何加载它。
【参考方案1】:
目前正则表达式中的第三组用引号括起来(引号是强制性的)。尝试使引号可选"?
- 表示零个或一个引号,同时使组内容非贪婪(.*?)
,因此它不会在组内捕获额外的引号:
'input.regex'='^(\\d+?),(.*?),"?(.*?)"?,([0-9.]*),(\\d*),(\\d*).*'
使用 regexp_replace 测试您的数据示例,我还在第 3 组周围添加了可选斜杠以将其从输出中删除:
with mytable as (
select stack(6,
'1,Monali,"abhc,jkjk",,23,23',
'2,mj,nhiijkla,67,23,60',
'7,jena,"kdjuu,hsysi,juw",3,34,23',
'1,Monali,"/"coppers bars","rods and profiles"/",,23,23',
'2,money,"/"COUPLING","FLANGES & CROSS OVER"/",67,23,60',
'2,money,"17",19"LCD PANEL FOR COMPUTER",67,23,60'
) as initial_data
)
select regexp_replace(initial_data,'^(\\d+?),(.*?),"?/?(.*?)/?"?,([0-9.]*),(\\d*),(\\d*).*',
'$1 || $2 || $3 || $4 || $5 || $6'
) as parsed_result
from mytable
结果(由两个竖线和空格分隔' || '
):
parsed_result
1 || Monali || abhc,jkjk || || 23 || 23
2 || mj || nhiijkla || 67 || 23 || 60
7 || jena || kdjuu,hsysi,juw || 3 || 34 || 23
1 || Monali || "coppers bars","rods and profiles" || || 23 || 23
2 || money || "COUPLING","FLANGES & CROSS OVER" || 67 || 23 || 60
2 || money || 17",19"LCD PANEL FOR COMPUTER || 67 || 23 || 60
因此,如果结果看起来不错,请在 DDL 表中使用此正则表达式:
'input.regex'='^(\\d+?),(.*?),"?/?(.*?)/?"?,([0-9.]*),(\\d*),(\\d*).*'
在整个数据集上仔细测试并检查空/空值,必要时修复正则表达式。
【讨论】:
它对我有用,我接受了答案。但是,当我在多列的情况下应用相同的逻辑时,即我的表中有 68 列。所以在“某个值”之后,它进入下一列。即“大学、科学和商业”,所以大学进入 desc 列但是科学和业务将在下一列中出现,请指导我如何为不同的列数扩展相同的逻辑。我的表中有 68 列,并希望为第 51 列实现相同的逻辑。我正在添加我的正则表达式在下一条评论中。请帮助。@leftjoin 'input.regex'='(.*?),(.*?),(.*?),(.*?),(.*?),(.*?) ,(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),( .*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.* ?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?) ,(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),( .*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.* ?),(.*?),(.*?),"?/?(.*?)/?"?,(.*?),(.*?),(.*?),(.* ?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?) ,(.*?),(.*?),(.*?),(.*?),(.*?)') @Varun 阅读文章:community.cloudera.com/t5/Community-Articles/… 从一列开始,也使用字符串开头的锚 ^ 像这样:'^(.*?),.*'
逐列添加并使用 regexp_replace 进行调试。
@Varun 在某些情况下,当列可以包含逗号(分隔符)并且不能被引用,并且下一列也可以包含逗号(分隔符)并且也不能被引用时,则无法形式化应该如何提取这些列的规则。仅包含数字的列或始终引用的列 + 字符串锚的结尾 - $ 在这种情况下会有所帮助。但是您应该了解如何提取的规则。懂了就可以了【参考方案2】:
试试这个标签:
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
【讨论】:
我试过了,但在这一行的情况下 -----> 2,money,"17",19"LCD PANEL FOR COMPUTER",67,23,60 它不起作用。 "17",19"LCD PANEL FOR COMPUTER" 是我的 desc 列值的值,但它在 desc 列中加载 17,在下一列中加载 19"LCD PANEL FOR COMPUTER。@diogoramos以上是关于在 Hive 中处理带和不带双引号的数据的主要内容,如果未能解决你的问题,请参考以下文章