前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >hive sql(网友1)—— 用户记录去重,两次记录间隔超过90天算新的记录总数及平均年龄

hive sql(网友1)—— 用户记录去重,两次记录间隔超过90天算新的记录总数及平均年龄

作者头像
大数据最后一公里
发布2021-08-05 10:27:09
1.3K0
发布2021-08-05 10:27:09
举报
文章被收录于专栏:大数据最后一公里

需求

代码语言:javascript
复制
用户记录去重,两次记录间隔超过90天算新的记录——此案例已征求网友同意

建表语句

代码语言:javascript
复制
create table wangyou(
    uid string,
    time string
);

数据

代码语言:javascript
复制
insert into wangyou values
("1","2021-01-01"),
("1","2021-02-03"),
("1","2021-04-02"),
("1","2021-05-07"),
("1","2021-07-02"),
("1","2021-08-15");

实现

代码语言:javascript
复制
select
    t2.uid,
    min(t2.time),
    t2.flag
from
    (select
        t1.uid,
        t1.time,
        t1.diff_day,
        case
            when t1.diff_day>90 and t1.diff_day <=180 then 1
            when t1.diff_day>180 and t1.diff_day <=270 then 2
            when t1.diff_day>270 and t1.diff_day <=360 then 3
            else 0
        end flag
    from(select
            uid,
            time,
            datediff(time,min(time)over(partition by uid order by time)) as diff_day
        from
            wangyou
        )t1
    )t2
group by t2.uid,t2.flag
;

结果

代码语言:javascript
复制
#网友要求的结果
uid  time  与当前满足条件的日期比较  间隔  是否满足条件
1  2021/1/1      1
1  2021/2/3  2021/1/1  33  
1  2021/4/2  2021/1/1  91  1
1  2021/5/7  2021/4/2  35  
1  2021/7/2  2021/4/2  91  1
1  2021/8/15  2021/7/2  44  

#实现语句的结果
Stage-Stage-1: Map: 1  Reduce: 1   Cumulative CPU: 5.82 sec   HDFS Read: 9756 HDFS Write: 189 SUCCESS
Stage-Stage-2: Map: 1  Reduce: 1   Cumulative CPU: 2.19 sec   HDFS Read: 6053 HDFS Write: 45 SUCCESS
Total MapReduce CPU Time Spent: 8 seconds 10 msec
OK
1  2021-01-01  0
1  2021-04-02  1
1  2021-07-02  2
Time taken: 60.922 seconds, Fetched: 3 row(s)

分析

代码语言:javascript
复制
#网友提供的计算逻辑
1.每个用户有多条记录,将每个用户最早的一个日期作为参数A,每条记录都与最小值相减,得到间隔天数;
2.如果间隔天数<=90,则参数A仍然是最早日期。如果>90,则将参数A更新为第一条大于90天的记录所在的天数;
如此循环,最终返回最早一条记录,以及间隔天数大于90的记录。例如左边的例子,最终uid=1去重后保留2021-01-01,2021-04-02,2021-07-02

#实现语句的分析
思路:
1、先按uid开窗排序,并且取出日期最小的一条数据,作为参考
2、计算每条数据的日期与参考日期的差值
3、判断差值所以哪个范围,这样会得到同一个范围的有多个flag
4、对flag去重,每个flag组里日期最小的数据就是去重之后要保留的结果

重点:
数据是有特征的,符合一定逻辑。本次的逻辑在于先将数据分段,90天一周期就是数据分类的特征。

扩展

代码语言:javascript
复制
1、本次默认数据的范围是360天内,如果是数据间隔时间比较长怎么处理;一是通常认为间隔时间特别久的数据不会再分析,因为离线每次按批处理,如此,历史数据都处理过的,只需要一段时间处理一次;二是如果对历史数据处理,数据量必然很大,也会采用按时间切割处理;三是可以多加几个case when将时间拉长,这种做法成本最小,最简洁;四是如果想实现动态的方式,可以使用udf函数
2、类似这种数据更新去重,找到数据分段逻辑,巧用flag去重,之前写过的连续登录的也是类似的逻辑,建议对比看一下

知识点

代码语言:javascript
复制
1、min(col):某组数据最小,可以作用于group by,也可以作用于over
2、case when:一个case when完整的语法包含case when then else end,如上;也可以简洁使用case when then end,如果不符合条件则返回null
3、datediff(日期1,日期2):返回日期1减日期2的差值

关注公众号:大数据最后一公里

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大数据最后一公里 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
大数据
全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档