Esto se hace mejor a nivel de aplicación, pero solo por diversión, aquí está a nivel de base de datos:
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`
- ver cómo funciona en vivo en un sqlfiddle
Tenga en cuenta que no hay funciones de retraso/adelanto en MySQL. Todo lo que puedes hacer es usar variables. El SELECT
cláusula se procesa una línea a la vez. Entonces puede asignar el valor de la fila actual en las últimas líneas de SELECT
cláusula y, por lo tanto, use esta variable como el valor de "la fila anterior" en las primeras líneas de SELECT
cláusula.
También tenga en cuenta que el ORDER BY
es muy importante. Una tabla no está ordenada. Los datos en un DBMS relacional no se clasifican a menos que especifique un orden con ORDER BY
cláusula.
- lea más sobre el uso de variables en consultas aquí
EDITAR:
Cámbialo a
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;