HIVE将时间戳列数据显示为NULL

时间:2018-09-03 02:37:57

标签: string hive timestamp hdfs hortonworks-sandbox

我正在尝试使用Hive创建一个外部表。以下是我运行的Hive查询:

create external table trips_raw
(
VendorID int,
tpep_pickup_datetime timestamp,
tpep_dropoff_datetime timestamp
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','  location '/user/taxi_trips/';

当我查看由上面的查询创建的“ trips_raw”表的输出时,我发现“ tpep_pickup_date_time”和“ tpep_dropoff_datetime”列在所有行中均为“ NULL”。我看过其他线程谈论的原因是Hive不接受'1/1/2018 11:13:00 AM'时间戳格式,但是问题是那是我在csv源数据中使用的时间戳格式(如您可以从此处的屏幕截图中看到)。

enter image description here

我可以将这两个时间戳列指定为“字符串”,并且Hive能够正确呈现它们,但是我仍然希望这2个列为“时间戳”类型,因此将这2列指定为“字符串”类型不是一个可行的选择。

我还使用来自本网站(https://community.hortonworks.com/questions/55266/hive-date-time-problem.html)的推荐尝试了以下技术,但没有成功:

  1. 使用'string'作为2个时间戳列的类型来创建'trips_raw'表。即使使用“字符串”类型,这也可以使结果表正确呈现时间戳。我使用的Hive命令如下所示:

    create external table trips_raw
    (
    VendorID int,
    tpep_pickup_datetime string,
    tpep_dropoff_datetime string
    )
    ROW FORMAT DELIMITED FIELDS TERMINATED BY ','  location 
    '/user/taxi_trips/';
    

当我查看结果表时,日期显示为字符串,如下面的屏幕截图所示。

enter image description here

但是正如我之前提到的,我希望时间列为时间戳类型而不是字符串类型。因此,在接下来的2个步骤中,我尝试创建一个空白表,然后从步骤1中创建的表中插入数据,但是这次将字符串转换为时间戳。

  1. 使用以下Hive命令创建一个名为“ trips_not_raw”的外部空白表:

    create external table trips_not_raw
    (VendorID int,
    tpep_pickup_datetime timestamp,
    tpep_dropoff_datetime timestamp
    );
    
  2. 使用以下Hive命令从“ trips_raw”表(此问题前面已提到)中插入数据:

    insert into table trips_not_raw select vendorid,
    from_unixtime(unix_timestamp(tpep_pickup_datetime, 'MM/dd/yyyy HH:mm:ss 
    aa')) as tpep_pickup_datetime,
    from_unixtime(unix_timestamp(tpep_dropoff_datetime, 'MM/dd/yyyy HH:mm:ss 
    aa')) as tpep_dropoff_datetime
    from trips_raw; 
    

这样做会将行插入到空白表“ trips_not_raw”中,但是从两个时间戳列中得到的结果仍然显示为“ Null”,如下面的屏幕快照所示:

enter image description here

是否有一种简单的方法将2个时间列存储为“时间戳”类型而不是“字符串”,但仍然能够在输出中正确呈现它们而不会看到“空/无”?

1 个答案:

答案 0 :(得分:1)

恐怕您需要解析时间戳列,然后将字符串转换为时间戳。例如,

select cast(regexp_replace('1/1/2018 11:13:00 AM', '(\\d{1,2})/(\\d{1,2})/(\\d{4})\\s(\\d{2}:\\d{2}:\\d{2}) \\w{2}', '$3-$1-$2 $4') as timestamp)

为方便起见,您可以创建和使用宏功能,例如

create temporary macro parse_date (ts string)
  cast(regexp_replace(ts, '(\\d{1,2})/(\\d{1,2})/(\\d{4})\\s(\\d{2}:\\d{2}:\\d{2}) \\w{2}', '$3-$1-$2 $4') as timestamp);

然后按如下所示使用它

select parse_date('1/1/2018 11:13:00 AM');