日期:2014-05-17  浏览次数:20670 次

一条sql查询语句 里面有用户、登录时间、登出时间 等字段写一条sql语句实现查询每个用户当天的的在线时间 见图

------解决方案--------------------
create table test([user] varchar(20),operate varchar(20),time datetime)
insert into test
select 'a','login','2013-5-20 08:00'
union all
select 'b','login','2013-5-20 09:00'
union all
select 'b','logout','2013-5-20 21:05'
union all
select 'a','logout','2013-5-20 23:05'
insert into test
select 'b','login','2013-5-20 21:10'
union all
select 'b','logout','2013-5-20 21:25'

select a.[user],sum(totalTime) totalTime from (
select a.[user],
datediff(minute,a.[time],isnull((select min([time]) from test b where operate='logout' and a.[user]=b.[user] and b.[time]>=a.[time]),a.[time])) totalTime
from test a where operate='login') a group by [user]
------解决方案--------------------
这个只能粗略的统计
因为有些异常登出日志表是记录不到的
这个时候只有登入没有登出

------解决方案--------------------
上面的脚本中如果只有登录而没有大于登录时间的退出记录,则统计时间为0,这个不正确,需要修改一下。
只有登录,没有退出,我认为是业务逻辑上的事情,首先应用程序应该去考虑解决,如果原始数据都是不完整性的,只能尽量去接近事实。比如:只有登录没有退出的,取一定范围内的最早一次退出记录

select a.[user],convert(char(5),dateadd(minute,sum(totalMinute),dateadd(hour,sum(totalHour),convert(varchar(20),getdate(),111))),114) from (
select a.[user],
datediff(hour,a.[time],isnull((select min([time]) from test b where operate='logout' 
and a.[user]=b.[user] and b.[time] between a.[time] and b.[time]+1),a.[time])) totalHour,
datediff(minute,a.[time],isnull((select min([time]) from test b where operate='logout' 
and a.[user]=b.[user] and b.[time] between a.[time] and b.[time]+1),a.[time]))%60 totalMinute
from test a where operate='login') a group by [user]

------解决方案--------------------
借楼主的宝地,请教一下版主,int 类型数据,有满足条件的记录,为何查询时where column=条件 确查询不到结果,以前遇过这种情况,通过dbcc checktable 检查出表错误,然后重建索引搞定,这次 dbcc checktable,发现表没有问题。。。。