是否可以通过类似
的表格在线计算时间logtype time
----------------
login 2:30
logout 2:45
login 3:20
logout 4:50
login 5:00
login 5:10
logout 6:00
它会有额外的登录,因为有时服务器崩溃并且不会添加注销。 你能在MySQL中做这样的事情还是你必须使用ColdFusion? 如果是这样,你会如何在MySQL / ColdFusion中做到这一点?
我想要的只是一个(粗略的)特定用户在线,小时,天,分钟等的总时间。
答案 0 :(得分:1)
(首先请参阅上面的说明。)
对于您将拥有的数据,通过配对连续的登录/注销对,您可以使用简单的 dateDiff([datepart],[date 1])处理数据以获取所需的信息如果你已经查询了数据,CF中的[日期2])功能可以找出差异。
对于数据处理,我建议在表中添加另一行 - 一行处理会话ID。这将确保您的登录/注销时间正确配对。然后,您可以设置类似以下内容的查询:
<cfquery name="getSession" datasource="[dsn]">
SELECT DISTINCT sessionID
FROM logTable
WHERE userID = <cfqueryparam cfsqltype="cf_sql_integer" value="[inputted userID]" />
</cfquery>
...然后,为了获得各个登录会话的登录时间,运行这样的循环输出它们......
<cfoutput query="getSessions">
<cfquery name="getSessionInfo" datasource="[dsn]">
SELECT
(SELECT time
FROM logTable
WHERE sessionID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#getSessions.sessionID# />
AND logType = <cfqueryparam cfsqltype="cf_sql_varchar" value="login" />)
AS loginTime,
(SELECT time
FROM logTable
WHERE sessionID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#getSessions.sessionID# />
AND logType = <cfqueryparam cfsqltype="cf_sql_varchar" value="logout" />)
AS logoutTime
FROM logTable
</cfquery>
[ancillary output - use your DateDiff here with getSessionInfo.loginTime and getSessionInfo.logoutTime as your two date/times and use the data as you need]
</cfoutput>
我对此的SQL可能有些偏差,但至少它指出了你正确的方向...希望这有帮助...随时联系我列表以获得更多解释。
答案 1 :(得分:0)
在我目前的项目中,我正在使用“用户活动”的另一个定义。对我来说,这是会话明星和最后一页请求之间的时间段。我没有按照这种格式跟踪活动时间,但如果我需要 - 我会这样做。
会话开始时 - 在表sessions
中创建可能如下所示的条目:
id (int) auto-incremented PK
sessionid (varchar) -- optional, session id string from ColdFusion
userid (int) FK
session_start (datetime) -- filled when created
last_request (datetime)
创建条目时,主键存储在用户会话中。
当用户发出请求时 - 更新last_request
属性。
当onSessionEnd
被解雇时,也可以更新它,但你需要从当前时间减去会话超时以获得最后一个请求时刻 - 这使得这无用。
此方法的其他好处是您可以非常轻松地获得每个用户的聚合数据。例如,这将选择秒数(未测试,可能是错误的):
<cfquery datasource="mydsn" name="qGetUserData">
select userid, sum(unix_timestamp(last_request) - unix_timestamp(session_start)) as timespan
from sessions
group by userid
</cfquery>
按句点过滤也很容易 - 只需添加where session_start ...
子句,对于特定用户的过滤也是如此。
答案 2 :(得分:0)
正如其他人所建议的那样,从长远来看,修改表结构是一种更好的方法。尝试配对日志记录(没有匹配的密钥)很困难,有时甚至是不可能的。略微修改的结构将更容易查询,并将产生更准确的结果。但是,如果您绝对无法修改表格,则可以计算粗略总计 - 如果您的记录ID是数字/顺序。
假设是“注销”记录总是在“登录”后插入。因此,注销的记录ID总是大于相应的“登录”。子查询可以将登录信息转换为成对:即当前和下一个登录记录。相应的“注销”记录ID将落在该范围内。匹配登录/注销后,使用日期/时间功能计算经过的时间(以分钟为单位)。然后按照您的意愿SUM()值并格式化结果。注意:显然,表格的正确索引是必须。
那就是说,这种方法只提供估算。它有几个缺陷:
无论如何,我不确定我的MySQL语法。但是忽略MS Sql Server特定的功能,这应该是关闭的。 MS SQL中的性能与适当的索引相当,并且大约有100K记录。
SELECT SUM(DateDiff(n, li.LogTime, lo.LogTime)) AS TotalTimeInMinutes
FROM (
SELECT li.RecordID, li.UserID, li.LogType, li.LogTime,
( SELECT MIN(t.RecordID) FROM YourTable t
WHERE t.UserID = li.UserID
AND t.LogType = li.logType
AND t.RecordID > li.RecordID
) AS NextRecordID
FROM YourTable li
WHERE li.UserID = 123
AND li.LogType = 'login'
)
li INNER JOIN YourTable lo ON lo.UserID = li.UserID
AND lo.LogType = 'logout'
AND lo.RecordID BETWEEN li.RecordID AND li.NextRecordID