关于hive时间的拆分(将两个时刻拆分成时间区间,做简单的操作)

今天有个同事问了一道面试题。面试题如下:

 

 他的意思是将时间拆分成下面右边的样子,开始时间是整数,结束时间是多少就是多少。

看到这个题目第一眼感觉挺简单的,就是拆。

大概的思路如下:

(1)给的是字符串,需要将数据拼接,拆分成具体的日期时间格式,然后才能操作。同时对数据开始时间进行规整操作

 (2)第二步,根据时刻只差,然后采用根据lateral view posexplode 爆炸函数,将一个一行数据,然后根据他的步长数据拆分成不用的行数据,

所谓的列转行数据。

(3)第三步,得到了拆分后的数据,似乎还是不能满足要求,这个时候我们就要用到我们经常使用到的连续性函数,lead.对这行的数据进行操作,

对相同的数据分组排序,升序操作,这样就能到到我们想要的数据,最后做一个简单的拼接,问题解决。

 

具体代码如下:

with mon as (
select '12:06-14:30' as date_time
union all
select '11:00-12:07' as date_time
) ,mon1 as (

select 
start_time,
end_time,
date_time,
hour(end_time)-hour(start_time) as hour_gap
from (
select 
concat('2021-11-23 ','',substr(split(date_time,'-')[0],0,2) ,':00',':00') as start_time,
concat('2021-11-23 ','',split(date_time,'-')[1] ,':00') as end_time,date_time
from mon 
) a 

) ,mon2 as (
select 
pos,
start_time,
end_time,
date_time,
from_unixtime(unix_timestamp(start_time)+pos*3600,'yyyy-MM-dd HH:mm:ss') as time_ll
from mon1 t
lateral view posexplode(split(space(hour_gap),' ')) tf as pos,val limit 5000

) 

select 
a.date_time,
case when a.time_ls is not null then concat(substr(time_ll,11,6),'-',substr(time_ls,11,6))
else concat(substr(time_ll,11,6),'-',substr(end_time,11,6)) end as time_lls

from (
select 
a.*,
lead(time_ll,1) over(partition by start_time,end_time order by pos ) as time_ls
from mon2 a 
) a 

注意的点:hive的时间是通过 小时*60*60进行时间相加的。所以这里采用了pos*60*60的步长对时间进行操作,得到结果。

 

posted on 2021-11-23 16:53  gxg123  阅读(1558)  评论(0编辑  收藏  举报

导航