在 Hive 中将时差拆分为最接近的半小时



我想在 Hive 中将时差拆分为最接近的半小时

以下是我打算实现的示例

User   Start_time            End_time              Duration
A      2020-05-05 06:45:00   2020-05-05 07:15:00   30
B      2020-05-05 10:15:00   2020-05-05 11:15:00   60

User   Start_time            End_time              Duration
A      2020-05-05 06:45:00   2020-05-05 07:00:00   15
A      2020-05-05 07:00:00   2020-05-05 07:15:00   15
B      2020-05-05 10:15:00   2020-05-05 10:30:00   15
B      2020-05-05 10:30:00   2020-05-05 11:00:00   30
B      2020-05-05 11:00:00   2020-05-05 11:15:00   15

计算floor(duration/30)所需的间隔数,然后使用lateral view posexplode(split(space(s.num_intervals),' '))生成行 请参阅代码中的其他逻辑:

with mytable as (--test dataset
select stack(3,
'A', '2020-05-05 06:45:00', '2020-05-05 07:15:00', 30,
'B', '2020-05-05 10:15:00', '2020-05-05 11:15:00', 60,
'C', '2020-05-05 10:00:00', '2020-05-05 12:15:00', 135
) as (Usr, Start_time, End_time, Duration)
)
select Usr, start_time, end_time, (unix_timestamp(end_time)-unix_timestamp(start_time))/60 Duration
from
(
select  Usr,
case when i.i=0 then start_time --first record
when i.i=1 then from_unixtime(unix_timestamp(start_time)+shift*60) 
else  from_unixtime(unix_timestamp(start_time)+shift*60+(i.i-1)*30*60)
end start_time,
case when i.i=num_intervals then end_time                             --end of range
when i.i=0 then from_unixtime(unix_timestamp(start_time)+shift*60) --first record
else from_unixtime(unix_timestamp(start_time)+shift*60+(i.i)*30*60)
end end_time
from
(--calculate required intervals and shift to 30 min
SELECT Usr,Start_time,End_time,
cast( floor(duration/30) as int) num_intervals,
case when (minute(Start_time) between 1 and 29) then 30-minute(Start_time)
when minute(Start_time) > 30 then 60-minute(Start_time)
else 30
end shift
FROM mytable 
)s
lateral view posexplode(split(space(s.num_intervals),' ')) i as i,x
)s
;

结果:

usr start_time          end_time            duration
A   2020-05-05 06:45:00 2020-05-05 07:00:00 15
A   2020-05-05 07:00:00 2020-05-05 07:15:00 15
B   2020-05-05 10:15:00 2020-05-05 10:30:00 15
B   2020-05-05 10:30:00 2020-05-05 11:00:00 30
B   2020-05-05 11:00:00 2020-05-05 11:15:00 15
C   2020-05-05 10:00:00 2020-05-05 10:30:00 30
C   2020-05-05 10:30:00 2020-05-05 11:00:00 30
C   2020-05-05 11:00:00 2020-05-05 11:30:00 30
C   2020-05-05 11:30:00 2020-05-05 12:00:00 30
C   2020-05-05 12:00:00 2020-05-05 12:15:00 15

也许我测试了并非所有可能的情况。请自行测试和调试。它适用于您的数据示例。

最新更新