最近的一个项目中有一个统计用户连续签到指定天数的需求,要是单单统计最后一次连续签到的次数也不是什么难事,偏偏需求是查询出指定时间段内连续签到指定天数的用户。
本来一开始觉着也不是很难,但思考了一会之后发现,要判断是否连续,用sql语句对我来说还是有不小的难度,于是乎开始google sql连续日期,也可能是本人不会搜索,找了半天没有找到自己想要的,或者对我有帮助的代码片段或者示例。
就这样白白浪费了一中午的时间,既然搜不到,那就自己想办法。既然难点是判断日期连续,我能不能这样做呢,把指定的时间段,拆分成N多个指定天数且连续的时间小时间段呢?貌似这样可行,说做就做,记录用户签到的表结构是这样的
用户每天仅能签到一次(记录一次),下面是查询满足条件的用户sql代码片段
1 declare @BeginDate datetime,--开始时间段 2 @EndDate datetime,--结束时间段 3 @Days int;--连续天数 4 5 set @BeginDate='2015-05-01'; 6 set @EndDate='2015-05-15'; 7 set @Days=3; 8 9 DECLARE @LoopTimes INT=0; 10 SET @LoopTimes=DATEDIFF(DAY,@BeginDate,@EndDate)-@Days+1; 11 12 IF OBJECT_ID('#TempUserSignin','U') IS NOT NULL 13 DROP TABLE #TempUserSignin; 14 15 CREATE TABLE #TempUserSignin 16 ( 17 UserID INT, 18 Counts INT 19 ); 20 21 WHILE (@LoopTimes>0) 22 BEGIN 23 24 INSERT INTO #TempUserSignin(UserID,Counts) 25 SELECT UserID,COUNT(1) AS Counts 26 FROM UserSigninLog WHERE LogTime BETWEEN @BeginDate AND DATEADD(DAY,@Days-1,@BeginDate)+'23:59:59.998' GROUP BY USERID; 27 28 SET @BeginDate=DATEADD(DAY,1,@BeginDate) 29 SET @LoopTimes=@LoopTimes-1; 30 END 31 32 SELECT MAX(Counts) AS Counts,UserID FROM #TempUserSignin WHERE Counts>=@Days GROUP BY UserID 33 DROP TABLE #TempUserSignin;
下面是用户签到记录表里面的测试数据
上面sql的执行结果如下:
我是低调的结尾,看到这就结束了哦