如何创建支持'dd-MMM-yyyy'格式的Hive表?解决日期列全为NULL问题
解决Hive外部表日期列显示NULL的问题
嘿,这个问题我之前处理过不少次!核心原因很简单:Hive的date类型默认只认yyyy-MM-dd格式的日期字符串,而你的CSV里是dd-MMM-yyyy(比如20-Mar-2018)这种格式,直接用date类型解析会失败,所以所有日期列都变成NULL了。下面给你两种靠谱的解决方案,按需选择:
方案一:先存为字符串,查询时转换(最通用,兼容所有Hive版本)
这种方法不受Hive版本限制,容错性也更高:
- 建表时把日期列定义为
string类型,同时别忘了指定CSV的字段分隔符(比如逗号分隔):
create external table new_stock ( Symbol String, Series String, Dat string, -- 先以字符串类型接收日期 Prev_Close float, Open_Price float, High_Price float, Low_Price float, Last_Price float, Close_Price float, Avg_Price float, Volume int, Turn_Over... -- 你的其他字段 ) row format delimited fields terminated by ',' -- 替换成你实际的分隔符 location '/your/hdfs/storage/path'; -- 替换成你的HDFS路径
- 查询时用Hive内置函数把字符串转成
date类型:- 如果是Hive 2.3及以上版本,用
date_parse最直接:
select Symbol, Series, date_parse(Dat, 'dd-MMM-yyyy') as Dat, -- 按CSV的日期格式转换 Prev_Close, Open_Price, -- 其他字段... from new_stock;- 如果是低版本Hive,用
unix_timestamp+to_date组合:
select Symbol, Series, to_date(unix_timestamp(Dat, 'dd-MMM-yyyy')) as Dat, -- 其他字段... from new_stock; - 如果是Hive 2.3及以上版本,用
方案二:建表时直接指定自定义日期格式(部分Hive版本支持)
如果你的Hive版本支持LazySimpleSerDe的日期格式参数,可以在建表时直接配置,这样查询时不用手动转换:
create external table new_stock ( Symbol String, Series String, Dat date, Prev_Close float, Open_Price float, High_Price float, Low_Price float, Last_Price float, Close_Price float, Avg_Price float, Volume int, Turn_Over... ) row format delimited fields terminated by ',' with serdeproperties ( "date.format" = "dd-MMM-yyyy" -- 告诉Hive按这个格式解析日期 ) stored as textfile location '/your/hdfs/storage/path';
注意:这个方法不是所有Hive版本都支持,如果测试后还是NULL,建议换回方案一。
额外注意事项
- 检查CSV里的日期字符串有没有多余空格或特殊字符(比如
20- Mar-2018带空格),如果有,转换时要先用trim(Dat)处理 - 确保建表时的字段顺序和CSV里的列顺序完全一致,顺序错了也会导致日期列读取错误
- 如果CSV有表头,建表时可以加上
tblproperties ("skip.header.line.count"="1")跳过表头行,避免表头被当成数据解析
内容的提问来源于stack exchange,提问作者Arunachalam
相关产品推荐
相关产品推荐

