如果您要在MySQL中进行,则需要自加入。脖子上的自我加入是很痛苦的,因为MySQL没有内置的Rownum功能。但这仍然可行。
首先,我们需要创建一个子查询来创建一个虚拟表模拟 SELECT rownum, user, timestamp FROM login
我们可以这样做。 http://sqlfiddle.com/#!2/bf6ef/2/0
SELECT @a:=@a+1 AS rownum, user, timestamp
FROM (
SELECT user, timestamp
FROM login
ORDER BY timestamp
) C,
(SELECT @a:=0) s
接下来,我们需要对这个虚拟表进行自我加入到本身的副本。在此结果集中,我们想要的是表中所有连续一对行的列表。那个查询是一个毛球 - 它使 结构化的 在 结构化查询语言. 。但是它有效。这里是: http://sqlfiddle.com/#!2/bf6ef/4/0
SELECT first.user AS fuser,
first.timestamp AS ftimestamp,
second.user AS suser,
second.timestamp as stimestamp,
TIMESTAMPDIFF(SECOND, first.timestamp, second.timestamp) AS timeloggedin
FROM (
SELECT @a:=@a+1 AS rownum, user, timestamp
FROM (
SELECT user, timestamp
FROM login
ORDER BY timestamp
) C,
(SELECT @a:=0) s
) AS first
JOIN (
SELECT @b:=@b+1 AS rownum, user, timestamp
FROM (
SELECT user, timestamp
FROM login
ORDER BY timestamp
) C,
(SELECT @b:=0) s
) AS second ON first.rownum+1 = second.rownum
比较连续行的整个技巧是
SELECT (virtual_table) AS first
JOIN (virtual_table) AS second ON first.rownum+1 = second.rownum
查询模式。 Rownum+1 = Rownum Thing与连续的行数聚集在一起。
接下来,我们需要总结该查询的结果,以获取每个用户登录的总时间。这样可以做到这样的工作:
SELECT user, SUM(timeloggedin) AS timeloggedin
FROM (
/* the self-joined query */
) AS selfjoin
GROUP BY user
ORDER BY user
看起来这样: http://sqlfiddle.com/#!2/bf6ef/5/0
这是整个查询。
SELECT user, SUM(timeloggedin) AS timeloggedin
FROM (
SELECT first.user AS user,
TIMESTAMPDIFF(SECOND, first.timestamp, second.timestamp) AS timeloggedin
FROM (
SELECT @a:=@a+1 AS rownum, user, timestamp
FROM (
SELECT user, timestamp
FROM login
ORDER BY timestamp
) C,
(SELECT @a:=0) s
) AS first
JOIN (
SELECT @b:=@b+1 AS rownum, user, timestamp
FROM (
SELECT user, timestamp
FROM login
ORDER BY timestamp
) C,
(SELECT @b:=0) s
) AS second ON first.rownum+1 = second.rownum
) AS selfjoin
GROUP BY user
ORDER BY user
对于曾经从事程序,算法和思考的人来说,这不是真正的直觉。但这就是您在SQL中进行这种连续的比较的方式。