在不改变数据类型string的情况下计算hive中两列string类型的时间差
Calculate time difference between two columns of string type in hive without changing the data type string
我正在尝试计算字符串数据类型的一行的两列之间的时间差。如果它们之间的时间差小于 2 小时,则 select 该行的第一列,否则如果时间差大于 2 小时,则 select 该行的第二列。可以通过将列转换为日期时间格式来完成,但我希望结果仅在字符串中。我怎样才能做到这一点?数据如下所示:
col1(字符串类型)
2018-07-16 02:23:00
2018-07-26 12:26:00
2018-07-26 15:32:00
col2(字符串类型)
2018-07-16 02:36:00
2018-07-26 14:29:00
2018-07-27 15:38:00
使用unix_timestamp() 将字符串时间戳转换为秒。
小时差为:
hive> select (unix_timestamp('2018-07-16 02:23:00')- unix_timestamp('2018-07-16 02:36:00'))/60/60;
OK
-0.21666666666666667
重要更新:只有当时区配置为UTC时,此方法才能正常工作。因为对于某些边缘情况的 DST 时区,Hive 在时间戳操作期间转换时间。考虑这个 PDT 时区的例子:
hive> select hour('2018-03-11 02:00:00');
OK
3
请注意,小时是 3
,而不是 2
。这是因为 2018-03-11 02:00:00
不能存在于 PDT 时区,因为恰好在 2018-03-11 02:00:00
时间被调整并成为 2018-03-11 03:00:00
。
转换为 unix_timestamp 时也会发生同样的情况。对于 PDT 时区 unix_timestamp('2018-03-11 03:00:00') 和 unix_timestamp('2018-03-11 02:00:00') 将 return相同的时间戳:
hive> select unix_timestamp('2018-03-11 03:00:00');
OK
1520762400
hive> select unix_timestamp('2018-03-11 02:00:00');
OK
1520762400
还有几个链接供您参考:
https://community.hortonworks.com/questions/82511/change-default-timezone-for-hive.html
http://boristyukin.com/watch-out-for-timezones-with-sqoop-hive-impala-and-spark-2/
也请看看这个jira:Hive should carry out timestamp computations in UTC
我认为您不需要将列转换为日期时间格式,因为您案例中的数据已经排序 (yyyy-MM-dd hh:mm:ss)。您只需要获取所有数字并将其放入一个字符串 (yyyyMMddhhmmss),然后您可以应用大于或小于 2 小时的选择(此处为 20000,因为小时后跟 mmss)。通过查看您的示例(假设 col2 > col1),此查询将起作用:
SELECT case when regexp_replace(col2,'[^0-9]', '')-regexp_replace(col1,'[^0-9]', '') < 20000 then col1 else col2 end as col3 from your_table;
我正在尝试计算字符串数据类型的一行的两列之间的时间差。如果它们之间的时间差小于 2 小时,则 select 该行的第一列,否则如果时间差大于 2 小时,则 select 该行的第二列。可以通过将列转换为日期时间格式来完成,但我希望结果仅在字符串中。我怎样才能做到这一点?数据如下所示:
col1(字符串类型)
2018-07-16 02:23:00
2018-07-26 12:26:00
2018-07-26 15:32:00
col2(字符串类型)
2018-07-16 02:36:00
2018-07-26 14:29:00
2018-07-27 15:38:00
使用unix_timestamp() 将字符串时间戳转换为秒。 小时差为:
hive> select (unix_timestamp('2018-07-16 02:23:00')- unix_timestamp('2018-07-16 02:36:00'))/60/60;
OK
-0.21666666666666667
重要更新:只有当时区配置为UTC时,此方法才能正常工作。因为对于某些边缘情况的 DST 时区,Hive 在时间戳操作期间转换时间。考虑这个 PDT 时区的例子:
hive> select hour('2018-03-11 02:00:00');
OK
3
请注意,小时是 3
,而不是 2
。这是因为 2018-03-11 02:00:00
不能存在于 PDT 时区,因为恰好在 2018-03-11 02:00:00
时间被调整并成为 2018-03-11 03:00:00
。
转换为 unix_timestamp 时也会发生同样的情况。对于 PDT 时区 unix_timestamp('2018-03-11 03:00:00') 和 unix_timestamp('2018-03-11 02:00:00') 将 return相同的时间戳:
hive> select unix_timestamp('2018-03-11 03:00:00');
OK
1520762400
hive> select unix_timestamp('2018-03-11 02:00:00');
OK
1520762400
还有几个链接供您参考:
https://community.hortonworks.com/questions/82511/change-default-timezone-for-hive.html
http://boristyukin.com/watch-out-for-timezones-with-sqoop-hive-impala-and-spark-2/
也请看看这个jira:Hive should carry out timestamp computations in UTC
我认为您不需要将列转换为日期时间格式,因为您案例中的数据已经排序 (yyyy-MM-dd hh:mm:ss)。您只需要获取所有数字并将其放入一个字符串 (yyyyMMddhhmmss),然后您可以应用大于或小于 2 小时的选择(此处为 20000,因为小时后跟 mmss)。通过查看您的示例(假设 col2 > col1),此查询将起作用:
SELECT case when regexp_replace(col2,'[^0-9]', '')-regexp_replace(col1,'[^0-9]', '') < 20000 then col1 else col2 end as col3 from your_table;