sql查询当天交易总额最大的用户信息_求连续操作(登录)数量(次数)最大的记录(用户)...

昨晚上老同事聚会,一个同事说道一个面试问题没有一个人做出来,就是求连续日期登录次数最大的用户,同事说借助 rownumber即可求解,由于是喝酒聊天,也没有说详细的解决过程。今天早上想了下,终于想到了具体的解决思路。

登录时间里面有详细的时分秒数据,而我们的题目只要求连续的天数,所以使用DATEDIFF函数可以解决,

DATEDIFF(d,LoginTime,getdate()) as diffDate ,

有多个用户都在登录,因此应该以用户名为分区,登录时间为顺序来计算rownumber,因此,就是下面的表达式:

ROW_NUMBER() over(partition by Name order by LoginTime desc) as rn

关键问题来了,如何求得连续的登录情况?

如果是连续的记录,那么 diffDate- rn 肯定是相同的!

OK,果然这种方式很巧妙,那么我们最终的SQL写出来也不难了。

开始动手,先构造一个表,插入初始数据:

/*求连续登录次数最多的用户*/

create tableUserLoginInfo(

IDint IDENTITY primary key,

Namevarchar(50) not null,

LoginTimedatetime not null)go

insertUserLoginInfo (Name,LoginTime)values('zhang','2015-11-10 12:01:50')

,('li','2015-11-11 11:01:50')

,('wang','2015-11-9 11:01:50');go

insert UserLoginInfo (Name,LoginTime) values('zhang','2015-11-11 12:01:50'),

('li','2015-11-11 12:01:50'),

('wang','2015-11-11 11:01:50'),

('zhang','2015-11-12 12:01:50'),

('li','2015-11-13 13:01:50'),

('wang','2015-11-12 11:01:50'),

('zhang','2015-11-13 12:01:50'),

('li','2015-11-14 11:01:50'),

('wang','2015-11-14 11:01:50');go

然后用下面的SQL得到结果:

select top 1Name,diffRn,COUNT(diffRn)asLoginCountfrom(select Name,diffDate,rn, (diffDate-rn) asdiffRnfrom(selectID,Name,DATEDIFF(d,LoginTime,getdate()) asdiffDate ,

ROW_NUMBER()over(partition by Name order by LoginTime desc) asrnfromUserLoginInfo

) t1

) t2group bydiffRn,Nameorder by LoginCount desc

答案是:

Name diffRn LoginCount

zhang14 4

如果注释掉 top 1,我们就知道这个结果的由来了:

Name diffRn LoginCount

zhang14 4li13 3wang14 2wang15 1li14 1wang13 1

这个问题也可以衍生出 求连续登录的用户,或者求连续登录15天的用户(比如QQ的签到功能),是不是很熟悉呢?

实际上,上面这个查询,遇到一天登录多次的情况下,统计是不准确的,例如,构造下面的测试数据:

insert UserLoginInfo (Name,LoginTime) values('zhang' ,'2015-11-10 12:01:50')

,('li' ,'2013-10-05 11:01:50')

,('li' ,'2013-10-06 11:01:50')

,('li' ,'2014-10-05 11:01:50')

,('li' ,'2014-10-06 11:01:50')

,('li' ,'2015-10-05 11:01:50')

,('li' ,'2015-10-06 11:01:50')

,('li' ,'2015-11-10 11:01:50')

,('li' ,'2015-11-11 11:01:50')

,('wang' ,'2015-11-09 11:01:50')

,('zhang' ,'2015-11-11 12:01:50')

,('li' ,'2015-11-11 12:01:50')

,('wang' ,'2015-11-11 11:01:50')

,('zhang' ,'2015-11-12 12:01:50')

,('li' ,'2015-11-13 13:01:50')

,('wang' ,'2015-11-12 11:01:50')

,('zhang' ,'2015-11-13 12:01:50')

,('li' ,'2015-11-14 11:01:50')

,('wang' ,'2015-11-14 11:01:50')

;

View Code

这时应该先去除某天的重复数据,才是正确的,所以查询应该做如下改进:

select --top 1

Name,diffRn,COUNT(diffRn)asLoginCountfrom(select Name,diffDate,rn, (diffDate-rn) asdiffRnfrom(selectName,

diffDate,

ROW_NUMBER()over(partition by Name order by diffDate asc) rnfrom(select distinct Name,DATEDIFF(d,LoginTime,getdate()) asdiffDatefromUserLoginInfo

) t0

) t1

) t2group bydiffRn,Nameorder by LoginCount desc;

结果是:

Name diffRn LoginCount

zhang14 4wang14 2li13 2li14 2li48 2li411 2li774 2wang13 1wang15 1

结果符合我们的预期,算是完整的答案了。

不知道别的同学还没有更好的解决方案?

-------------------------------------------

PS:如果你经常会在程序中写这样复杂的SQL,推荐你使用PDF.NET SOD框架的SQL-MAP功能,将SQL写在配置文件中,集中管理,并且方便跨数据库移植。

SOD框架 PDF.NET_SOD Ver 5.3.6.1125 已经发布,喜欢的朋友可以下载当前这个最新的稳定版本,有问题,可以加框架的QQ群:PDF.NET SOD高级群 18215717

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/**---- select * from KuChun select * from Sell select sum(SellNum)as Sumd,SellID,ProductType from Sell group by SellID,ProductType select * from KuChun t1 left join (select SellID, sum(sellnum)as snum,ProductType from Sell group by SellID,ProductType)t2 on t1.ShopID=t2.SellID and t1.ProductType=t2.ProductType order by t1.ShopID SELECT T1.SHOPID, T1.PRODUCTTYPE, T1.KNUM, (select ISNULL(sum(t2.sellnum),0) from Sell t2 where t2.sellid = t1.shopid and t2.producttype= t1.productType) sumsell FROM KuChun T1 order by t1.shopid; select T1.SHOPID, T1.PRODUCTTYPE, T1.KNUM, ISNULL(sum(t2.sellnum),0) sellnum from KuChun t1 left join Sell t2 on t2.sellid = t1.shopid and t2.producttype= t1.productType group by T1.SHOPID, T1.PRODUCTTYPE, T1.KNUM order by t1.shopid; select T1.SHOPID, T1.PRODUCTTYPE, sum(T1.KNUM) knum, ISNULL(sum(t2.sellnum),0) sellnum from KuChun t1 left join Sell t2 on t2.sellid = t1.shopid and t2.producttype= t1.productType group by T1.SHOPID, T1.PRODUCTTYPE order by t1.shopid; select c.*,a.s_score as '01课程 score',b.s_score as '02课程 score' from score a,score b left join student c on b.s_id = c.s_id where a.s_id = b.s_id and a.c_id = '01' and b.c_id = '02' and a.s_score > b.s_score; **/ ---ALTER TABLE KuChun ALTER COLUMN Knum int; select * from student t2 select * from Course t3 select * from Teacher t4 select * from Score t1 -- 50、查询下月过生日的学生 select * from( select ss.* ,datename(mm,ss.s_birth) as wk,datename(mm,getdate()) as wk1 from Student ss )tt where tt.wk=tt.wk1+1 -- 49、查询本月过生日的学生 select ss.*,datename(mm,ss.s_birth) from Student ss where datename(mm,getdate())=datename(mm,ss.s_birth) -- 48、查询下周过生日的学生 select * from( select ss.*,datename(wk,ss.s_birth)as'周数', cast( datename(wk,ss.s_birth) as decimal)- datename(wk,getdate()) as wk from Student ss )tt where tt.wk=1 -- 47、查询本周过生日的学生 select ss.* from Student ss where datename(wk,ss.s_birth)=datename(wk,get

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值