hive使用技巧-日期区间合并

需求描述

​ 将同一用户的多段连续日期范围,进行合并。

id开始时间结束时间
12020-01-012020-01-07
12020-01-082020-01-20
12020-01-212020-01-30

要合并成

id开始时间结束时间
12020-01-012020-01-20
12020-01-212020-01-30

解决思路

  1. 根据id分组开窗,根据开始时间、结束时间排序,取每行的上一条记录的结束时间。
  2. 如果当前行的开始时间小于上条记录的结束时间,则当前行与上一行所属在相同的合并周期内
  3. 根据id和合并周期分组,取最大、最小时间。就得出每个合并周期内的开始结束时间。
-- 1. 根据id分组开窗,根据开始时间、结束时间排序,取每行的上一条记录的结束时间。
SELECT startdate,
       enddate,
       granularity1,
       lag(enddate)OVER (PARTITION BY granularity1
       ORDER BY startdate, enddate) AS lagenddate
FROM VALUES
    (1, '2020-01-01', '2020-04-31', 'Value1', 'ValueA'),
    (1, '2020-04-01', '2020-06-30', 'Value1', 'ValueB'),
    (1, '2020-07-01', '2020-09-30', 'Value1', 'ValueC'),
    (1, '2020-10-01', '2020-10-30', 'Value1', 'ValueD')
    AS t(id, startdate, enddate, granularity1, granularity2)
-- 2. 如果当前行的开始时间小于上条记录的结束时间,则当前行与上一行所属在相同的合并周期内
SELECT startdate,
       enddate,
       lagenddate,
       granularity1,
       sum(CASE
       WHEN lagenddate >= startdate THEN 0
       ELSE 1
       END)OVER (PARTITION BY granularity1
       ORDER BY startdate) AS groupid
FROM (
    SELECT startdate,
           enddate,
           granularity1,
           lag(enddate)OVER (PARTITION BY granularity1
           ORDER BY startdate) AS lagenddate
    FROM VALUES
    (1, '2020-01-01', '2020-04-31', 'Value1', 'ValueA'),
    (1, '2020-04-01', '2020-06-30', 'Value1', 'ValueB'),
    (1, '2020-07-01', '2020-09-30', 'Value1', 'ValueC'),
    (1, '2020-10-01', '2020-10-30', 'Value1', 'ValueD')
    AS t(id, startdate, enddate, granularity1, granularity2)
  ) AS t
--3. 根据id和合并周期分组,取最大、最小时间。就得出每个合并周期内的开始结束时间。
SELECT min(startdate) AS startdate,
       max(enddate) AS   enddate,
       granularity1,
       groupid
FROM (
  SELECT startdate,
         enddate,
         lagenddate,
         granularity1,
         sum(CASE
         WHEN lagenddate >= startdate THEN 0
         ELSE 1
         END)OVER (PARTITION BY granularity1
         ORDER BY startdate) AS groupid
  FROM (
    SELECT startdate,
           enddate,
           granularity1,
           lag(enddate)OVER (PARTITION BY granularity1
           ORDER BY startdate) AS lagenddate
    FROM VALUES
    (1, '2020-01-01', '2020-04-31', 'Value1', 'ValueA'),
    (1, '2020-04-01', '2020-06-30', 'Value1', 'ValueB'),
    (1, '2020-07-01', '2020-09-30', 'Value1', 'ValueC'),
    (1, '2020-10-01', '2020-10-30', 'Value1', 'ValueD')
    
    AS t(id, startdate, enddate, granularity1, granularity2)
  ) AS t
) AS t
GROUP BY granularity1, groupid
;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值