问题:现有一堆的时间段,s
表示开始时间,e
表示结束时间。需要将所有时间段合并。
合并规则:
- 如果2个时间段有重叠则合并成一个时间。
- 不重叠则作为一个单独的时间段。
with base_tb as (
SELECT named_struct('s', s, 'e', e) span
from (
select *
from values
(1, 3),
(2, 7),
(5, 6),
(4, 11),
(10, 11),
(11, 14)
as (s, e)
) as a
)
--每次一个新元素和最后一个元素比较,看是融合进去还是新增一个
select aggregate(spans, array(spans[0]), (acc, x) ->
if(x.s <= acc[size(acc)-1].e,
--剔除最后一个,做一个新的融合进去
array_union(array_remove(acc, acc[size(acc)-1]),
array(named_struct(
's', acc[size(acc)-1].s,
'e', array_max(array(acc[size(acc)-1].e, x.e))))),
array_union(acc, array(x))
)
)
from (
select array_sort(spans) spans
from (
select collect_list(span) spans
from base_tb
) as a
)