TSQL--查找连续登陆用户
--==========================================
需求:有一个用户登陆日志表,记录用户每次登陆时间,然后想查找用户按天连续登陆的情况,找出每次连续登陆的最早时间和最后时间以及连续登陆天数。
--===========================================
由于长久未写此类SQL,有点手生,本着走一步算一步的精神,慢慢来。
首先查看日志表
SELECT [Uid],[loginDate]FROM [dbo].[Member_LoginLog]WHERE [UID]=268
由于按天计算连续登陆,表中时间精确到毫秒,很难肉眼看出数据是否连续,于是考虑转换数据
而又由于我们只关心最早登陆时间和最后登陆时间,因此我们可以先按照天来统计用户最早登陆时间和最后登陆时间,并将时间转换成对应天数
--============================================== --统计出用户每天最早登陆时间和最后登陆时间 SELECT T1.[UID] ,DATEDIFF(DAY,'2014-01-01',LoginDate) AS DiffDays ,MAX(LoginDate) AS MaxLoginDate ,MIN(LoginDate) AS MinLoginDate INTO [dbo].[Member_LoginLog_Status1] FROM [dbo].[Member_LoginLog] T1 GROUP BY T1.[UID],DATEDIFF(DAY,'2014-01-01',LoginDate) --====================================== --查看效果 SELECT [UID] ,[DiffDays] ,[MaxLoginDate] ,[MinLoginDate] FROM [dbo].[Member_LoginLog_Status1] WHERE UID=268
从上图很容易看出第二天没连续登陆,是不是很容易看啊
接下来就是查找联系的天数了,如果我们按照UID分组,然后对DiffDays来排序求出排名来,依据DiffDays的增长量和RID量便可以判断出天数是否连续
SELECT ROW_NUMBER()OVER(PARTITION BY UID ORDER BY [DiffDays] ASC) AS RID, T1.* FROM [dbo].[Member_LoginLog_Status1] T1 WHERE [UID]=268
这样我们便可以使用表的自连接来查找连续的登录,由于需要按照用户和天数来算出排名,因此我们可以先建立索引
CREATE CLUSTERED INDEX CIX_UID_Days ON [dbo].[Member_LoginLog_Status1] ([UID],[DiffDays] )
然后再求连续区间:
--========================================== --查找连续的登录 ;WITH Tem AS( SELECT ROW_NUMBER()OVER(PARTITION BY UID ORDER BY [DiffDays] ASC) AS RID, T1.* FROM [dbo].[Member_LoginLog_Status1] T1 ) ,Tem1 AS( SELECT ROW_NUMBER()OVER(PARTITION BY T1.[UID],T1.[DiffDays] ORDER BY T2.[diffdays]-T1.[diffdays] DESC) AS RID, T1.[UID], T1.MinLoginDate, T2.MaxLoginDate, T1.[diffdays] AS MinDiffDays, T2.[diffdays] AS MAXDiffDays FROM Tem AS T1 INNER JOIN Tem AS T2 ON T1.UID=T2.UID AND T1.[diffdays]<=T2.[diffdays] AND T2.[diffdays]-T1.[diffdays]= T2.RID-T1.RID ) SELECT [UID], MinLoginDate, MaxLoginDate, MinDiffDays, MAXDiffDays INTO [dbo].[Member_LoginLog_Status2] FROM Tem1 AS T1 WHERE T1.RID=1 --========================================= --检查结果 SELECT [UID] ,[MinLoginDate] ,[MaxLoginDate] ,[MinDiffDays] ,[MAXDiffDays] FROM [dbo].[Member_LoginLog_Status2] WHERE [UID]=268
找出连续的区间后,我们会发现有很多区间不是最大连续区间,如第5天到第17天连续,但是比之更大的区间还有第3天到第17天,对于这种问题,解决办法就是依据maxDiffDays分组,求出最小的minDiffDays
由于此时要按照用户和maxDiffDays分组,然后按照MinDiffDays排序求最小值,因此先建立索引
CREATE CLUSTERED INDEX CIX_UID_MAXDiffDays ON [AccMain_101].[dbo].[Member_LoginLog_Status2] ([UID],MAXDiffDays,MinDiffDays ASC)
然后再查询:
--==================================== --求出最大连续区间 ;WITH CTE1 AS( SELECT ROW_NUMBER()OVER(PARTITION BY [UID],MAXDiffDays ORDER BY MinDiffDays ASC) AS RID, [UID], MinLoginDate, MaxLoginDate, MinDiffDays, MAXDiffDays FROM [AccMain_101].[dbo].[Member_LoginLog_Status2] AS T1 ) INSERT INTO [dbo].[Member_LoginLog_Status3]([Uid],[firstLoginDate],[lastLoginDate],[loginNumber]) SELECT [UID], MinLoginDate, MaxLoginDate, T1.MAXDiffDays-MinDiffDays AS ContinueDays FROM CTE1 T1 WHERE T1.RID=1 --================================== --查看结果 SELECT [Uid],[firstLoginDate],[lastLoginDate],[loginNumber]FROM [dbo].[Member_LoginLog_Status3]WHERE [UID]=268
查询结果:
结果正是我们想要的,因此打完收工,回家吃饭。
--===============================================
总结:其实查找连续或查找孤岛这类原理,都是利用自连接然后看增长是否连续,多折腾几遍就好。
--===============================================
在wwwwgou的回复中,指出一条更快捷的计算方式,同样使用排名来计算,但不使用关联,而是计算排名与登陆天数的差值,如果登陆天数连续增长,则排名也连续增长,两者的差值保持不变;如果登陆天数不连续,则登陆天数增长的值就会比排名增长的值高,这时两者的差值就会变大。
如下图:
随着天数不连续的次数增加,[天数-排名]的值会不断增大,因此可以使用[天数-排名]来分组,便可以定位到连续区间。
PS: 不会出现两个不同连续区间的[天数-排名]值一样的情况
查找代码:
--======================================== --感谢wwwwgou提供, --此代码已略做修改 SELECT [Uid], mindt = MIN(mindt), maxdt = MAX(maxdt), logdays = COUNT(*) FROM ( SELECT [Uid], RowNo = ROW_NUMBER() OVER(PARTITION BY [Uid] ORDER BY DATEDIFF(DAY,'2014-01-01', loginDate)), DiffDay = DATEDIFF(DAY,'2014-01-01', loginDate), mindt = MIN(loginDate), maxdt = MAX(loginDate) FROM dbo.Member_LoginLog GROUP BY [Uid], DATEDIFF(DAY,'2014-01-01', loginDate) ) T GROUP BY [Uid], [RowNo] - DiffDay ORDER BY [Uid], minDt
对wwwwgou筒子再次表示婶婶地感谢。
--===============================================
请原谅我苍白的讲解,让您们只能看代码。
妹子骚猴就上,不要着急。
TSQL--查找连续登陆用户相关推荐
- 超详细解析:用sql查找连续登陆7天或者登陆天数最多的用户id
# 方法一:查询连续登陆7天的用户id和登陆天数 -- 第一步:用户登录日期去重 select distinct date(date) as 日期,id from tb_user; -- 第二步:用r ...
- mysql 连续七天不登录_【SQL】查询连续登陆7天以上的用户
查询7天连续登陆用户这个问题很经典,解决方法也有很多,这里我讲一下笔者的方法,希望对大家有帮助. 具体思路: 1.因为每天用户登录次数可能不止一次,所以需要先将用户每天的登录日期去重. 2.再用row ...
- 查询连续登陆7天以上的用户 Mysql
查询7天连续登陆用户这个问题很经典,解决方法也有很多,这里我讲一下笔者的方法,希望对大家有帮助. 具体思路: 1.因为每天用户登录次数可能不止一次,所以需要先将用户每天的登录日期去重. 2.再用row ...
- mysql连续登录5天以上用户,【SQL】查询连续登陆7天以上的用户
查询7天连续登陆用户这个问题很经典,解决方法也有很多,这里我讲一下笔者的方法,希望对大家有帮助. 具体思路: 1.因为每天用户登录次数可能不止一次,所以需要先将用户每天的登录日期去重. 2.再用row ...
- 求用户最大连续登陆天数mysql实现
用户连续登陆 一.规定时间内用户最大连续登陆天数 二.user_login表字段(所有用户登陆信息) 三.分解步骤 1.where初步筛选 2.窗口函数分组排序 4.计算获得连续的字段 5.分组计算连 ...
- 超详细解析:使用SQL语句查询连续登陆7天的用户信息
假设有如下表tb_user,现输出连续登陆7天的用户id 方法一思路: 1.因为每天用户登录次数可能不止一次,所以需要先将用户每天的登录日期去重. 2.再用row_number() over(part ...
- SQL计算连续登陆天数大于等于3天的用户
其中给出了用户(id)和用户登陆时间(dt)两列 其中要处理把登陆时间截取到日,然后根据id和登陆时间dt进行去重,然后得到如下的数据集 再进行下面的代码 select id, sdate, edat ...
- HIVE面试题原理详解 统计用户连续交易的总额、连续登陆天数、连续登陆开始和结束时间、间隔天数
HIVE面试题原理详解 统计用户连续交易的总额.连续登陆天数.连续登陆开始和结束时间.间隔天数 友情提示 创建数据表 添加数据 流程图 第一步分析(子表a) 第二步分析(子表b) 第三步分析(子表c) ...
- SQL——最大连续登录天数、当前连续登录天数、最大连续未登录天数问题、连续登陆N天用户、连续座位号
问题: 最大连续登录天数 当前连续登录天数 最大连续未登录天数 连续登陆3天用户(三种方法) 选出连续座位的编号 前三个问题所用数据: 原数据表:user_active表 表字段:用户.新增日期.活跃 ...
最新文章
- 【web安全】Xss Exploits and Defense翻译2
- Memcached----2-3
- React-引领未来的用户界面开发框架-读书笔记(一)
- Linux中创建用户并且配置sudo权限,百分百简单有效
- ajax 入参为list_ajax传递参数list对象或传递数组对象到后台
- 8.在第7步的基础上为我们的程序添加负载均衡支持
- 010 Editor v8.0.1(32 - bit) 算法逆向分析、注册机编写
- 第四届组织医学与再生医学国际学术研讨会(CTERM-BT 2019)
- 教师计算机知识培训内容,新学期教师计算机培训方案
- 15串行加法器和并行加法器原理
- COMSOL仿真软件入门学习(一)
- 大伽「趣」说AI:腾讯云在多个场景中的AI落地实践
- 在ipad上的几款远程桌面工具使用体会
- 单链表就地逆置(Java版)
- AD620单电源应变片测量电路分析
- 快速复制粘贴小工具txmouse
- 文本两端对齐及将表单打印在A4上
- PLSQL无客户端连接ORACLE
- Oracle ORION IO 测试工具
- [python]线性规划作图及求解
热门文章
- windows下,linux下elasticsearch安装插件head插件的步骤
- python怎么实现黑客攻击英国_注意!你的隐私就是这样被黑客获取的
- java刷机_java非智能手机能不能通过刷机安装一个安卓智能系统
- 教你如何找网络上的图片素材
- 「译文」你必须掌握的 7 种 JavaScript 错误类型
- 数据库完整性概念和数据库安全性概念之间的区别与联系
- 16 bit float 存储_小数在内存中是如何存储的,揭秘诺贝尔奖级别的设计(长篇神文)...
- 固定ip_1分钟学会查看跨境卫士费用和选择固定IP
- Java教程:Java return语句
- python set函数原理,Python之set详解