我有一个带有字段ID,PLAYER,TIMESTAMP和ACTION的MySQL表LOGIN_LOG。 ACTION可以是“登录”或“注销”。只有大约20%的登录具有附带的注销行。对于那些做的人,我想计算平均持续时间。
我在考虑像
这样的东西select avg(LL2.TIMESTAMP - LL1.TIMESTAMP)
from LOGIN_LOG LL1
inner join LOGIN_LOG LL2 on LL1.PLAYER = LL2.PLAYER and LL2.TIMESTAMP > LL1.TIMESTAMP
left join LOGIN_LOG LL3 on LL3.PLAYER = LL1.PLAYER
and LL3.TIMESTAMP between LL1.TIMESTAMP + 1 and LL2.TIMESTAMP - 1
and LL3.ACTION = 'login'
where LL1.ACTION = 'login' and LL2.ACTION = 'logout' and isnull(LL3.ID)
这是最好的方法吗,还是有效率呢?
答案 0 :(得分:1)
鉴于您拥有的数据,您可能没有更快的速度,因为您必须查看LOGIN和LOGOUT记录,并确保同一用户没有其他LOGIN(或LOGOUT?)记录两者之间。
或者,找到一种方法来确保断开连接记录注销,以便数据完整(而不是完成20%)。但是,查询可能仍然必须确保满足所有条件,因此它不会对查询有所帮助。
如果您可以将数据转换为LOGIN和相应LOGOUT时间都在同一记录中的格式,那么您可以极大地简化查询。我不清楚SessionManager是否适合你。
答案 1 :(得分:0)
您是否有可以超时会话的SessionManager类型对象?因为可以在那里记录超时,并且您可以从该时间和超时时间获得最后的活动时间。
或者您在网站/服务上记录所有活动,因此您可以直接查询网站/服务访问持续时间,并查看他们执行的活动。对于网站,Apache日志分析器可能会生成所需的统计信息。
答案 2 :(得分:0)
我同意JeeBee,但SessionManager类型对象的另一个优点是你可以处理sessionEnd事件并写入一个带有活动时间的注销行。这样,您可能会从20%的伴随注销行转到100%随附的注销行。因此,查询活动时间对于所有会话来说都是微不足道和一致的。
答案 3 :(得分:0)
如果只有20%的用户实际注销,则此搜索不会为您提供每个会话的准确时间。衡量一般用户会话的平均时间的更好方法是采取行动之间的平均时间,或平均。每页的时间。然后,这可以乘以每次访问的平均页数/操作数,以提供更准确的时间。
此外,您可以确定平均值。每个页面的时间,然后得到你的会话结束时间=到那一点的会话时间+在他们的最后一页上花费的平均时间。这将为您提供更精细(和准确)的每个会话花费的时间度量。
关于给定的SQL,它似乎比你真正需要的更复杂。在数据库外部的代码中,这种统计操作通常可以更好地处理/更易于维护,您可以使用您选择的任何语言的全部功能,而不仅仅是SQL用于统计计算的相当复杂的能力