--==========================================

需求:有一个用户登陆日志表,记录用户每次登陆时间,然后想查找用户按天连续登陆的情况,找出每次连续登陆的最早时间和最后时间以及连续登陆天数。

--===========================================

由于长久未写此类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--查找连续登陆用户相关推荐

  1. 超详细解析:用sql查找连续登陆7天或者登陆天数最多的用户id

    # 方法一:查询连续登陆7天的用户id和登陆天数 -- 第一步:用户登录日期去重 select distinct date(date) as 日期,id from tb_user; -- 第二步:用r ...

  2. mysql 连续七天不登录_【SQL】查询连续登陆7天以上的用户

    查询7天连续登陆用户这个问题很经典,解决方法也有很多,这里我讲一下笔者的方法,希望对大家有帮助. 具体思路: 1.因为每天用户登录次数可能不止一次,所以需要先将用户每天的登录日期去重. 2.再用row ...

  3. 查询连续登陆7天以上的用户 Mysql

    查询7天连续登陆用户这个问题很经典,解决方法也有很多,这里我讲一下笔者的方法,希望对大家有帮助. 具体思路: 1.因为每天用户登录次数可能不止一次,所以需要先将用户每天的登录日期去重. 2.再用row ...

  4. mysql连续登录5天以上用户,【SQL】查询连续登陆7天以上的用户

    查询7天连续登陆用户这个问题很经典,解决方法也有很多,这里我讲一下笔者的方法,希望对大家有帮助. 具体思路: 1.因为每天用户登录次数可能不止一次,所以需要先将用户每天的登录日期去重. 2.再用row ...

  5. 求用户最大连续登陆天数mysql实现

    用户连续登陆 一.规定时间内用户最大连续登陆天数 二.user_login表字段(所有用户登陆信息) 三.分解步骤 1.where初步筛选 2.窗口函数分组排序 4.计算获得连续的字段 5.分组计算连 ...

  6. 超详细解析:使用SQL语句查询连续登陆7天的用户信息

    假设有如下表tb_user,现输出连续登陆7天的用户id 方法一思路: 1.因为每天用户登录次数可能不止一次,所以需要先将用户每天的登录日期去重. 2.再用row_number() over(part ...

  7. SQL计算连续登陆天数大于等于3天的用户

    其中给出了用户(id)和用户登陆时间(dt)两列 其中要处理把登陆时间截取到日,然后根据id和登陆时间dt进行去重,然后得到如下的数据集 再进行下面的代码 select id, sdate, edat ...

  8. HIVE面试题原理详解 统计用户连续交易的总额、连续登陆天数、连续登陆开始和结束时间、间隔天数

    HIVE面试题原理详解 统计用户连续交易的总额.连续登陆天数.连续登陆开始和结束时间.间隔天数 友情提示 创建数据表 添加数据 流程图 第一步分析(子表a) 第二步分析(子表b) 第三步分析(子表c) ...

  9. SQL——最大连续登录天数、当前连续登录天数、最大连续未登录天数问题、连续登陆N天用户、连续座位号

    问题: 最大连续登录天数 当前连续登录天数 最大连续未登录天数 连续登陆3天用户(三种方法) 选出连续座位的编号 前三个问题所用数据: 原数据表:user_active表 表字段:用户.新增日期.活跃 ...

最新文章

  1. 【web安全】Xss Exploits and Defense翻译2
  2. Memcached----2-3
  3. React-引领未来的用户界面开发框架-读书笔记(一)
  4. Linux中创建用户并且配置sudo权限,百分百简单有效
  5. ajax 入参为list_ajax传递参数list对象或传递数组对象到后台
  6. 8.在第7步的基础上为我们的程序添加负载均衡支持
  7. 010 Editor v8.0.1(32 - bit) 算法逆向分析、注册机编写
  8. 第四届组织医学与再生医学国际学术研讨会(CTERM-BT 2019)
  9. 教师计算机知识培训内容,新学期教师计算机培训方案
  10. 15串行加法器和并行加法器原理
  11. COMSOL仿真软件入门学习(一)
  12. 大伽「趣」说AI:腾讯云在多个场景中的AI落地实践
  13. 在ipad上的几款远程桌面工具使用体会
  14. 单链表就地逆置(Java版)
  15. AD620单电源应变片测量电路分析
  16. 快速复制粘贴小工具txmouse
  17. 文本两端对齐及将表单打印在A4上
  18. PLSQL无客户端连接ORACLE
  19. Oracle ORION IO 测试工具
  20. [python]线性规划作图及求解

热门文章

  1. windows下,linux下elasticsearch安装插件head插件的步骤
  2. python怎么实现黑客攻击英国_注意!你的隐私就是这样被黑客获取的
  3. java刷机_java非智能手机能不能通过刷机安装一个安卓智能系统
  4. 教你如何找网络上的图片素材
  5. 「译文」你必须掌握的 7 种 JavaScript 错误类型
  6. 数据库完整性概念和数据库安全性概念之间的区别与联系
  7. 16 bit float 存储_小数在内存中是如何存储的,揭秘诺贝尔奖级别的设计(长篇神文)...
  8. 固定ip_1分钟学会查看跨境卫士费用和选择固定IP
  9. Java教程:Java return语句
  10. python set函数原理,Python之set详解