Isso requer uma auto-joia se você quiser fazê-lo no MySQL. É uma dor no pescoço fazer uma auto-joia porque o MySQL não tem função de Rownum. Mas ainda é factível.
Primeiro, precisamos criar uma subconeração para criar uma tabela virtual simulando SELECT rownum, user, timestamp FROM login
o que podemos fazer assim. 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
Em seguida, precisamos fazer uma auto-joia desta tabela virtual para uma cópia de si mesma. O que queremos neste conjunto de resultados é uma lista de todos os pares consecutivos de linhas da tabela. Essa consulta é uma bola de cabelo - coloca o estruturada dentro linguagem de consulta estruturada. Mas funciona. Aqui está: 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
Todo o truque para comparar linhas consecutivas é o
SELECT (virtual_table) AS first
JOIN (virtual_table) AS second ON first.rownum+1 = second.rownum
padrão de consulta. A coisa de Rownum+1 = Rownum reúne linhas com números consecutivos de linha juntos.
Em seguida, precisamos resumir o resultado dessa consulta para obter o tempo total conectado a cada usuário. Isso vai funcionar assim:
SELECT user, SUM(timeloggedin) AS timeloggedin
FROM (
/* the self-joined query */
) AS selfjoin
GROUP BY user
ORDER BY user
Isso se parece com o seguinte: http://sqlfiddle.com/#!2/bf6ef/5/0
Esta é toda a consulta montada.
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
Não é realmente intuitivo para alguém acostumado a procedimento, algorítmico e pensando. Mas é assim que você faz esse tipo de comparação consecutiva na linha no SQL.