SparkSQL统计——连续3月或以上

 前言:本章用到了开窗函数,不了解的可以去看看。

SQL开窗函数(窗口函数)详解_流水随清风的博客-CSDN博客_sql开窗函数

 

数据源下载:

链接: https://pan.baidu.com/s/1WMz8B-xJZjOoMmlaLurjZg

提取码: eetv

 

数据源展示:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyI5Lqu57uZ5oiR5oqE5Luj56CB,size_20,color_FFFFFF,t_70,g_se,x_16

 

案例实现要求:统计连续3月或以上都有购买记录的用户个数

 

思路讲解:

1.以当前时间为基准值,获取到前面两月的日期以及后面两月的日期

通过lag和lead获取,注意它们的默认值,以及over中的排序为升序。

 

2.计算连续3月:

情况1——前两月和当前月份连续

(当前日期减前第一个月份的结果再减1)除以2)<=  30

   and

(当前日期减前第二个月份的结果再减1)除以3)<=30 

 

情况2——前一月与当前日期及后一月连续

(当前日期减前第一个月份的结果再减1)除以2)<=  30

   and

(后第一个月减当前日期的结果再减1)除以2)<= 30 

 

情况3——后两月和当前日期连续

(后第一个月减当前日期的结果再减1)除以2)<=30 

   and

(后第二个月减当前日期的结果再减1)除以3)<=30 

 

满足这三种情况其中之一即实现3月或以上连续

 

3.根据用户id进行去重

 

答疑:

1.为什么判断连续条件要减去1  且  <= 30 ?

答:两个连续月份之间最大的跨度为61天,如:7.1——8.31 ,我们减去1,然后除去月份个数2,刚刚好可以完成这个过滤操作。

       三个连续月份之间最大的跨度为91天,如:7.1——9.30,我们减去1,然后除去月份个数3,也是刚刚好可以完成这个过滤操作。

如图所示

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyI5Lqu57uZ5oiR5oqE5Luj56CB,size_20,color_FFFFFF,t_70,g_se,x_16

 

 

实现源码:

  def main(args: Array[String]): Unit = {


    val spark = SparkSession.builder().appName("lianxu_month").master("local[*]").enableHiveSupport().getOrCreate()



    spark.read.option("header","true").csv("/home/桌面/lianxu.csv").createOrReplaceTempView("data")


    //TODO 统计出连续3月都有购买记录的用户个数
    spark.sql(
      """
         select
            count(distinct(user_id)) count
         from
             (select
                user_id,
                event_date,
                lag(event_date,2,"1970-01-01") over(distribute by user_id sort by event_date) lag_2,
                lag(event_date,1,"1970-01-01") over(distribute by user_id sort by event_date) lag_1,
                lead(event_date,1,"9999-99-99") over(distribute by user_id sort by event_date) lead_1,
                lead(event_date,2,"9999-99-99") over(distribute by user_id sort by event_date) lead_2
             from
                (select
                  user_id,
                  to_date(event_time) event_date
                from
                  data)t1 )t2
         where
             (datediff(event_date,lag_1)-1)/2 <= 30 and (datediff(event_date,lag_2)-1)/3 <=30
             or
             (datediff(event_date,lag_1)-1)/2 <= 30 and (datediff(lead_1,event_date)-1)/2 <=30
             or
             (datediff(lead_1,event_date)-1)/2 <= 30 and (datediff(lead_2,event_date)-1)/3 <=30
        """.stripMargin).show()


    spark.stop()


  }

 

其实无论判断连续几个月份都没关系,掌握这个运算规则就行了~

 

 

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月亮给我抄代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值