Hive SQL经典面试题

最近发现一道大数据面试经常会问的SQL题目:统计连续登录的三天及以上的用户(或者类似的:连续3个月充值会员用户、连续N天购买商品的用户等),下面就来记录一下解题思路。
要求输出格式:


+---------+--------+-------------+-------------+--+
|   uid   | times  | start_date  |  end_date   |
+---------+--------+-------------+-------------+--+

首先建表:

create table test.user_login_info(user_id string  COMMENT '用户ID'
,login_date date COMMENT '登录日期'
)
row format delimited
fields terminated by ',';

原始数据:

导入原始数据:

hdfs dfs -put /root/user_login_info.txt  /user/hive/warehouse/test.db/user_login_info/

查看:

select * from user_login_info;
+--------------------------+-----------------------------+
| user_login_info.user_id  | user_login_info.login_date  |
+--------------------------+-----------------------------+
| user01                   | 2018-02-28                  |
| user01                   | 2018-03-01                  |
| user01                   | 2018-03-02                  |
| user01                   | 2018-03-04                  |
| user01                   | 2018-03-05                  |
| user01                   | 2018-03-06                  |
| user01                   | 2018-03-07                  |
| user02                   | 2018-03-01                  |
| user02                   | 2018-03-02                  |
| user02                   | 2018-03-03                  |
| user02                   | 2018-03-06                  |
+--------------------------+-----------------------------+

解题思路:
1.先把数据按照user_id分组,login_date升序

selectuser_id,login_date,row_number() over(partition by user_id order by login_date asc) as rankfrom user_login_info
;结果:
+----------+-------------+-------+
| user_id  | login_date  | rank  |
+----------+-------------+-------+
| user01   | 2018-02-28  | 1     |
| user01   | 2018-03-01  | 2     |
| user01   | 2018-03-02  | 3     |
| user01   | 2018-03-04  | 4     |
| user01   | 2018-03-05  | 5     |
| user01   | 2018-03-06  | 6     |
| user01   | 2018-03-07  | 7     |
| user02   | 2018-03-01  | 1     |
| user02   | 2018-03-02  | 2     |
| user02   | 2018-03-03  | 3     |
| user02   | 2018-03-06  | 4     |
+----------+-------------+-------+

2.用 login_date - rank 得到的差值日期如果是一样的,则说明是连续登录的

selectt1.user_id as user_id,t1.login_date as login_date,date_sub(t1.login_date , t1.rank) as date_difffrom(selectuser_id,login_date,row_number() over(partition by user_id order by login_date asc) as rankfrom user_login_info)t1
;结果:
+----------+-------------+-------------+
| user_id  | login_date  |  date_diff  |
+----------+-------------+-------------+
| user01   | 2018-02-28  | 2018-02-27  |
| user01   | 2018-03-01  | 2018-02-27  |
| user01   | 2018-03-02  | 2018-02-27  |
| user01   | 2018-03-04  | 2018-02-28  |
| user01   | 2018-03-05  | 2018-02-28  |
| user01   | 2018-03-06  | 2018-02-28  |
| user01   | 2018-03-07  | 2018-02-28  |
| user02   | 2018-03-01  | 2018-02-28  |
| user02   | 2018-03-02  | 2018-02-28  |
| user02   | 2018-03-03  | 2018-02-28  |
| user02   | 2018-03-06  | 2018-03-02  |
+----------+-------------+-------------+

3.根据 user_id 和 date_diff 分组,login_date 的最小时间即 start_date ,最大时间即 end_date,取分组后的count>=3的即为最终结果

selectt2.user_id as user_id,count(*) as times,min(t2.login_date) as start_date,max(t2.login_date) as end_datefrom (selectt1.user_id as user_id,t1.login_date as login_date,date_sub(t1.login_date , t1.rank) as date_difffrom(selectuser_id,login_date,row_number() over(partition by user_id order by login_date asc) as rankfrom user_login_info)t1)t2
group by t2.user_id,t2.date_diff
having count(*) >= 3
;结果:
+----------+--------+-------------+-------------+
| user_id  | times  | start_date  |  end_date   |
+----------+--------+-------------+-------------+
| user01   | 3      | 2018-02-28  | 2018-03-02  |
| user01   | 4      | 2018-03-04  | 2018-03-07  |
| user02   | 3      | 2018-03-01  | 2018-03-03  |
+----------+--------+-------------+-------------+

以上为一种解决方案,大佬们如果有更好的方案欢迎留言交流。

Hive SQL经典面试题:统计连续登陆的三天及以上的用户相关推荐

  1. sql案例分析:统计连续登陆、日活、蚂蚁森林、排名等

    # 当天新用户hive -e \'select count(1) from hm2.daily_helper \where guid not in (select guid from hm2.hist ...

  2. SQL经典面试题及答案

    转载自:http://blog.csdn.net/hwq1987/article/details/6670300 SQL经典面试题及答案 2007年07月27日 星期五 上午 08:42 1.一道SQ ...

  3. 【笔试/面试】SQL 经典面试题

    基本概念 (1)any/all,构成 where 子句的条件判断,any:表示或(or)的概念,all:则表示与(and)的概念,这两个关键字的出现是为了语句的简化: (2)先分组再做聚合,逻辑上也应 ...

  4. Hive SQL复杂场景实现(1) —— 连续发单天数

    本文同时发表于我的个人博客http://xinyuwg.com,访问该链接以获得详细信息与更好的阅读体验. 本文为原创内容,未经允许请勿转载. 至今在数据分析岗摸爬滚打已有一年,尚且不敢说自己挖掘洞见 ...

  5. sql经典面试题50题

    总结不甚清楚的有:10,19,20,22,24,25,28,41,42 --1.查询"01"课程比"02"课程成绩高的学生的信息及课程分数 --1.1.查询同时 ...

  6. 数据库SQL经典面试题详解

    SQL面试题不外乎增删改查,对于这种类型的题目,我的经验是先把每个表的关联关系搞清楚,它们之间是通过哪些字段关联的,可以在纸上画出关联图,再去编写SQL就不会那么头大了. 下面是四张表的关联关系图: ...

  7. SQL经典面试题(二)

    有3个表S,C,SC S(SNO,SNAME)代表(学号,姓名)  //主键:SNO    //多个人,多门课 3张表   ,SC 关系表 C(CNO,CNAME,CTEACHER)代表(课号,课名, ...

  8. oracle sql经典面试题,经典SQL面试题2

    题目: 一张名为workersalary的表,要求查询出全部信息,并且salary最高的三个人按升序排列在结果的最开头,其余的人按原有顺序排列.这个sql如何写? 解答: (1)题意理解 假如原先的表 ...

  9. SQL经典面试题--留存率问题

    留存率 定义:某一天新增用户在之后的第n天仍然登录的比例,称为第n日留存率 例如:20220101新增100人, 20220102这100人中登录了60人,次日留存率为60% 20220103这100 ...

最新文章

  1. linux 文件删除恢复
  2. Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-
  3. android显示圆圈动画,Android实现3个圆圈的动画
  4. alarm/pause
  5. 【免费毕设】基于jsp的新闻发布系统(论文)
  6. python工资高还是java-未来Java、大数据、Python哪个前景更好,薪资更高?
  7. Android USB Audio accessory设备
  8. 深入理解的JavaScript函数编程
  9. Firefox和Chrome浏览器导出书签
  10. 无盘服务器缓存,深入研究无盘服务器缓存
  11. 小程序加入人脸识别_微信小程序实现人脸识别
  12. 伯努利试验及概率方程 二项式分布 期望值与方差
  13. 如何成为一名区块链工程师? | 附学习资源
  14. meta标签http-equiv属性实现自动刷新页面和重定向
  15. LeetCode解题汇总目录
  16. 怎样使用ApowerMirror实现将手机屏幕投屏到电脑
  17. 学习使用php实现生成模糊图片的方法类整理
  18. 北京交通大学计算机学院硕士导师,北京交通大学计算机与信息技术学院研究生导师:王涛...
  19. 被iPhone 11带火的UWB产业链有哪些?
  20. php格式是什么文件》,php是什么文件(php是什么文件格式?)

热门文章

  1. 无水印的html5制作软件,无水印剪辑视频
  2. 【论文笔记-NER综述】A Survey on Deep Learning for Named Entity Recognition
  3. UnityShader17.1:ESM 阴影技术
  4. matlab施加阶跃相应,典型环节与及其阶跃响应
  5. signature=161034cb9eebb9b66e71be6081528fe7,Alternative Semantics for Verdi
  6. 阴阳师服务器维护3月25日,《阴阳师》手游3月21日维护更新公告
  7. 知云文献翻译打不开_PDF翻译/PDF边划边译,最好的PDF翻译软件
  8. 电脑输入英文字母间距太大
  9. SpringBoot高级_与安全
  10. DICOM:基于DCMTK实现C-FIND SCU