在 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 中处理带和不带双引号的数据的主要内容,如果未能解决你的问题,请参考以下文章

从熊猫数据框保存不带双引号的csv文件

Pivotal GPDB:如何在表和列上运行不带双引号的查询

从 Access 导出不带双引号的 CSV 文件

db2怎样使卸出的字符型字段不带双引号,用啥关键字

将 MySQL 导出为 CSV,一些列带引号,一些不带引号

带双引号的 PHP/SQL 准备语句