SparkSQL 统计某天每个用户访问页面次数前N的的页面

前两天有小老弟面试遇到如下问题:
在这里插入图片描述

那应该如何完成这个SQL语句的书写呢?
测试数据:

val rdd = spark.sparkContext.makeRDD(
	 List(
	   ("2018-01-01", 1, "www.baidu.com", "10:01"),
	   ("2018-01-01", 2, "www.baidu.com", "10:01"),
	   ("2018-01-01", 1, "www.sina.com", "10:01"),
	   ("2018-01-01", 3, "www.baidu.com", "10:01"),
	   ("2018-01-01", 3, "www.baidu.com", "10:01"),
	   ("2018-01-01", 1, "www.sina.com", "10:01")
	 )
)

解题思路:

  • 首先第一步:肯定需要根据user_id,page_id进行分组操作,将相同用户的访问页面归为一类,并统计出每个用户访问相同页面的次数
    spark
         .sql(
           """
             |select
             |     userId,
             |     page,
             |     count(page) as page_count
             | from
             |     t_log
             | group by
             |     userId,page
             |""".stripMargin)
         .show()
    
    执行结果:
    +------+-------------+----------+
    |userId|         page|page_count|
    +------+-------------+----------+
    |     2|www.baidu.com|         1|
    |     3|www.baidu.com|         2|
    |     1|www.baidu.com|         1|
    |     1| www.sina.com|         2|
    +------+-------------+----------+
    
  • 接下来第二步:通过窗口函数中的排名函数对相同用户分区,并且按照页面访问量降序排列
    spark
        .sql(
           """
             |select
             |   *
             |from
             |   (
             |     select
             |       userId,
             |       page,
             |       page_count,
             |       rank()
             |       over(partition by userId order by page_count desc) as rank
             |     from
             |         (
             |           select
             |             userId,
             |             page,
             |             count(page) as page_count
             |           from
             |             t_log
             |           group by
             |             userId,page
             |			)
             |     )
             |""".stripMargin)
         .show()	
    
    执行结果:
    +------+-------------+----------+----+
    |userId|         page|page_count|rank|
    +------+-------------+----------+----+
    |     1| www.sina.com|         2|   1|
    |     1|www.baidu.com|         1|   2|
    |     3|www.baidu.com|         2|   1|
    |     2|www.baidu.com|         1|   1|
    +------+-------------+----------+----+
    
  • 最后,保留Rank排名前10的结果
    spark
        .sql(
           """
             |select
             |   *
             |from
             |   (
             |     select
             |       userId,
             |       page,
             |       page_count,
             |       rank()
             |       over(partition by userId order by page_count desc) as rank
             |     from
             |         (
             |           select
             |             userId,
             |             page,
             |             count(page) as page_count
             |           from
             |             t_log
             |           group by
             |             userId,page
             |			)
             |     )
    		 |where
    		 | 	rank < 10
             |""".stripMargin)
         .show()	
    
    执行结果:
    +------+-------------+----------+----+
    |userId|         page|page_count|rank|
    +------+-------------+----------+----+
    |     1| www.sina.com|         2|   1|
    |     1|www.baidu.com|         1|   2|
    |     3|www.baidu.com|         2|   1|
    |     2|www.baidu.com|         1|   1|
    +------+-------------+----------+----+
    

总结:

主要考察SQL的基本语法及窗口函数的使用

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值