關於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的步長對時間進行操作,得到結果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM