C'est mieux fait au niveau de l'application, mais juste pour le plaisir, c'est ici au niveau de la base de données :
select `user`, `start`, `stop`, diff from (
select
t.*
, if(@prev_user = `user`, (`stop` - @prev) * -1, 0) as diff
, @prev := `start`
, @prev_user := `user`
from
t
, (select @prev := null, @prev_user := null) var_init
order by `user`, `start` desc
) sq
order by `user`, `start`
- le voir fonctionner en direct dans un sqlfiddle
Notez qu'il n'y a pas de fonctions de retard/avance dans MySQL. Tout ce que vous pouvez faire, c'est utiliser des variables. Le SELECT
clause est traitée une ligne à la fois. Vous pouvez donc affecter la valeur de la ligne courante dans les dernières lignes du SELECT
clause et donc utiliser cette variable comme valeur de "la ligne précédente" dans les premières lignes du SELECT
clause.
Notez également que la clause ORDER BY
c'est tres important. Un tableau n'est pas trié. Les données dans un SGBD relationnel ne sont pas triées sauf si vous spécifiez un ordre avec le ORDER BY
clause.
- en savoir plus sur l'utilisation des variables dans les requêtes ici
MODIFIER :
Changez-le en
UPDATE inactivitytmp
JOIN (
SELECT
inactivitytmp.*
, if(@prev_user_id = `user_id`, (`end_ts` - @prev) * -1, 0) as diff2
, @prev := `start_ts`
, @prev_user_id := `user_id`
FROM
inactivitytmp
, (SELECT @prev := null, @prev_user_id := null) var_init
ORDER BY `user_id`, `start_ts` DESC
) query_alias
ON inactivitytmp.user_id=query_alias.user_id AND inactivitytmp.start_ts=q uery_alias.start_ts AND inactivitytmp.end_ts=query_alias.end_ts
SET inactivitytmp.diff=query_alias.diff2;