创建表test_user_login_3days

create table test_user_login_3days(user_id int,login_date date
);
insert into test_user_login_3days values (123,'2018-08-02');
insert into test_user_login_3days values (123,'2018-08-03');
insert into test_user_login_3days values (123,'2018-08-04');
insert into test_user_login_3days values (456,'2018-11-02');
insert into test_user_login_3days values (456,'2018-12-09');
insert into test_user_login_3days values (456,'2018-11-04');
insert into test_user_login_3days values (456,'2018-11-05');
insert into test_user_login_3days values (789,'2018-01-01');
insert into test_user_login_3days values (789,'2018-04-23');
insert into test_user_login_3days values (789,'2018-09-10');
insert into test_user_login_3days values (789,'2018-09-11');
insert into test_user_login_3days values (789,'2018-09-12');
insert into test_user_login_3days values (10001,'2018-04-23');
insert into test_user_login_3days values (10001,'2018-04-24');
insert into test_user_login_3days values (10001,'2018-09-11');
insert into test_user_login_3days values (10001,'2018-09-12');
+---------+------------+
| user_id | login_date |
+---------+------------+
|     123 | 2018-08-02 |
|     123 | 2018-08-03 |
|     123 | 2018-08-04 |
|     456 | 2018-11-02 |
|     456 | 2018-12-09 |
|     789 | 2018-01-01 |
|     789 | 2018-04-23 |
|     789 | 2018-09-10 |
|     789 | 2018-09-11 |
|     789 | 2018-09-12 |
|   10001 | 2018-04-23 |
|   10001 | 2018-04-24 |
|   10001 | 2018-09-11 |
|   10001 | 2018-09-12 |
|   10001 | 2018-09-12 |
|     456 | 2018-11-05 |
|     456 | 2018-11-04 |
+---------+------------+
17 rows in set (0.00 sec)

用到的函数:lead(column, 1, null):取字段column提前一行的数据。
用法详见:SQL SERVER LEAD和LAG函数

思路:

生成新字段lead_1daylead_2day分别表示把login_date列提前一行、两行:

select user_id, login_date,lead(login_date, 1) over(partition by user_id order by login_date) as lead_1day,    # 提前一行的数据lead(login_date, 2) over(partition by user_id order by login_date) as lead_2day     # 提前两行的数据
from test_user_login_3days
+---------+------------+------------+------------+
| user_id | login_date | lead_1day  | lead_2day  |
+---------+------------+------------+------------+
|     123 | 2018-08-02 | 2018-08-03 | 2018-08-04 |
|     123 | 2018-08-03 | 2018-08-04 | NULL       |
|     123 | 2018-08-04 | NULL       | NULL       |
|     456 | 2018-11-02 | 2018-11-04 | 2018-11-05 |
|     456 | 2018-11-04 | 2018-11-05 | 2018-12-09 |
|     456 | 2018-11-05 | 2018-12-09 | NULL       |
|     456 | 2018-12-09 | NULL       | NULL       |
|     789 | 2018-01-01 | 2018-04-23 | 2018-09-10 |
|     789 | 2018-04-23 | 2018-09-10 | 2018-09-11 |
|     789 | 2018-09-10 | 2018-09-11 | 2018-09-12 |
|     789 | 2018-09-11 | 2018-09-12 | NULL       |
|     789 | 2018-09-12 | NULL       | NULL       |
|   10001 | 2018-04-23 | 2018-04-24 | 2018-09-11 |
|   10001 | 2018-04-24 | 2018-09-11 | 2018-09-12 |
|   10001 | 2018-09-11 | 2018-09-12 | 2018-09-12 |
|   10001 | 2018-09-12 | 2018-09-12 | NULL       |
|   10001 | 2018-09-12 | NULL       | NULL       |
+---------+------------+------------+------------+
17 rows in set (0.05 sec)

这时,如果lead_2daylead_1day相差1天,并且lead_1daylogin_date也相差1天,那么就意味着存在连续三天。
加入判断语句:where (lead_2day - lead_1day) = 1 and (lead_1day - login_date) = 1

select * from    (select *, lead(login_date, 1) over(partition by user_id order by login_date) as lead_1day,      # 提前一行的数据lead(login_date, 2) over(partition by user_id order by login_date) as lead_2day from  # 提前两行的数据test_user_login_3days) as A
where (lead_2day - lead_1day) = 1 and (lead_1day - login_date) = 1

也就是说,用户123和用户789连续登陆了。

+---------+------------+------------+------------+
| user_id | login_date | lead_1day  | lead_2day  |
+---------+------------+------------+------------+
|     123 | 2018-08-02 | 2018-08-03 | 2018-08-04 |
|     789 | 2018-09-10 | 2018-09-11 | 2018-09-12 |
+---------+------------+------------+------------+
2 rows in set (0.00 sec)

最终代码

写法一:
select A.user_id from (select *, lead(login_date, 1) over(partition by user_id order by login_date) as lead_1day,      # 提前一行的数据lead(login_date, 2) over(partition by user_id order by login_date) as lead_2day from  # 提前两行的数据test_user_login_3days) as A
where (lead_2day - lead_1day) = 1 and (lead_1day - login_date) = 1
写法二:
select user_id from (select user_id, datediff(lead(login_date, 1) over(partition by user_id order by login_date), login_date) as diff_1day, datediff(lead(login_date, 2) over(partition by user_id order by login_date), login_date) as diff_2dayfrom test_user_login_3days) as A
where diff_1day = 1 and diff_2day = 2;

ps.如果是sql就不用子查询了。

sql选取连续三天登录的用户相关推荐

  1. hive sql系列(三)——求所有用户和活跃用户的总数及平均年龄

    每天分享一个sql,帮助大家找到sql的快乐 需求:求所有用户和活跃用户的总数及平均年龄 建表语句 create table user_age(dt string,user_id string,age ...

  2. mysql查询连续三天100以上_一个SQL查询连续三天的流量100以上的数据值【SQql Server】...

    题目 有一个商场,每日人流量信息被记录在这三列信息中:序号 (id).日期 (date). 人流量 (people).请编写一个查询语句,找出高峰期时段,要求连续三天及以上,并且每天人流量均不少于10 ...

  3. 查询连续3天登录的用户

    一.创建表 CREATE TABLE `log` (`user_id` int(11) NOT NULL,`create_time` datetime(0) NULL DEFAULT NULL ) E ...

  4. 最近连续三周活跃用户数

    连续三周活跃用户:在当前日期之前三周的周活表中,此用户都存在 周活表特点按照mid_id进行了去重 因此如果用户,在连续三周的周活中出现,那么就会有3条对应的记录 周活表:dws_dv_detail_ ...

  5. 连续7天登录MySQL求解

    Ptypora-copy-images-to: img typora-root-url: img 1 建表语句 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = ...

  6. 数仓体系——最近七天内连续三天活跃用户数

    方法1-通过连续日期排名 首先我们筛选出最近七天的每日数据,属于每日设备行为,也就是说一条数据等于一次活跃 这一步对每日设备行为去重(正常情况下不写也可以,因为每日设备 行为理论上来说是已经去过重的) ...

  7. Hive面试题系列1: 求连续三天购买指定需求

    1.数据源 cat /home/root/order.txt 001 zs p001 2020-02-04 002 zs p005 2020-03-05 003 zs p006 2020-03-06 ...

  8. SQL实现筛选出连续3天登录用户与窗口函数

    阅读目录 还原试题 SQL窗口函数 一.窗口函数有什么用 二.什么是窗口函数 三.如何使用 1.专用窗口函数rank 2.其他专业窗口函数 3.聚合函数作为窗口函数 4.注意事项 四.总结 解题思路 ...

  9. python实现简单的用户密码登录控制(输入三次就锁定用户)

    问题描述 我们经常在登录一些网站的时候,发现我们如果连续的输错好几次密码,我们的帐号就被锁定起来了,那这个过程是如何实现的呢?本程序主要就是解决以下3件事情 1.输入用户名密码 2.认证成功并显示欢迎 ...

最新文章

  1. poj 1904 King's Quest
  2. IDC发布对话式人工智能白皮书|附下载
  3. 【FPGA】双端口RAM的设计(同步读写)
  4. 运维-系统架构师经验总结:
  5. 图像处理之基于阈值模糊
  6. 计算机技术应用在教学中的优势,[浅谈多媒体在教学中的应用及优势] 多媒体教学的优势...
  7. autocad完全应用指南_建筑绘图慢?580页的AUTOCAD完全自学必备指南,高效绘图不求人...
  8. java 8 list和数组之间的相互转换
  9. selenium 页面经常改变元素_selenium用jquery改变元素属性
  10. java能看懂代码不会写_为什么很多学习Java的人能看懂代码,但就是不会写!
  11. Liferay CE 6.1安装教程
  12. 2017.6.15 数字表格 思考记录
  13. 基于JAVA+SpringMVC+Mybatis+MYSQL的社区养老服务网站
  14. SCCM TP4部署Office2013
  15. android alertdialog view,Android AlertDialog 方法setView(view,0,0,0,0)开发自定义对话框
  16. RDD的创建 -Scala educoder
  17. 利用GPU加速的软件
  18. CCS+C6678LE开发记录14:多核协作之OMP与IPC方式的较量
  19. H264的码率控制方法(CBR, VBR, CVBR,ABR)
  20. 了解torch.nn.DataParallel

热门文章

  1. upc 潜入苏拉玛 多源bfs + 并查集 + 思维
  2. 考研复试英文自我介绍模板(学长已上岸)
  3. python +pygame 制作五子连珠小游戏
  4. 全球及中国小型风力发电行业研究及十四五规划分析报告(2022)
  5. 7-3 五彩斑斓的黑 (20 分)pat乙级
  6. 北斗导航 | 基于性能导航(PBN)涉及术语
  7. ArcGIS总结——矢量数据分析之网络分析(上)
  8. 宇视设备搜索工具_【聚焦】2019版中国纸箱行业供应商搜索引擎、全球瓦楞行业设备前沿技术报告将于4月瓦楞展现场首发!...
  9. 在微信项目的通讯录页面中增加添加联系人功能
  10. Node.js实现网络新闻爬虫及搜索功能(四)