Cela nécessite une auto-jointure si vous le faites dans MySQL. C'est une douleur dans le cou de faire une auto-jointure car MySQL n'a pas de fonction Rownum intégrée. Mais c'est toujours faisable.
Tout d'abord, nous devons créer une sous-requête pour créer une table virtuelle simulant SELECT rownum, user, timestamp FROM login
que nous pouvons faire comme ça. 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
Ensuite, nous devons faire une auto-jointure de cette table virtuelle à une copie de lui-même. Ce que nous voulons dans cet ensemble de résultats est une liste de toutes les paires de lignes consécutives dans le tableau. Cette requête est une boule de cheveux - elle met le structuré dans Langage de requêtes structurées. Mais ça marche. C'est ici: 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
L'astuce pour comparer les lignes consécutives est le
SELECT (virtual_table) AS first
JOIN (virtual_table) AS second ON first.rownum+1 = second.rownum
modèle de requête. Le Rownum + 1 = Rownum Thing rassemble les lignes avec des numéros de ligne consécutifs ensemble.
Ensuite, nous devons résumer le résultat de cette requête pour obtenir le temps total connecté pour chaque utilisateur. Cela fonctionnera comme ceci:
SELECT user, SUM(timeloggedin) AS timeloggedin
FROM (
/* the self-joined query */
) AS selfjoin
GROUP BY user
ORDER BY user
Cela ressemble à ceci: http://sqlfiddle.com/#!2/bf6ef/5/0
C'est toute la requête assemblée.
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
Ce n'est pas vraiment intuitif pour quelqu'un habitué à la pensée procédurale, algorithmique. Mais c'est ainsi que vous faites ce type de comparaison consécutive dans SQL.