Dit kan beter op applicatieniveau, maar gewoon voor de lol, hier is het op databaseniveau:
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`
- zie het live werken in een sqlfiddle
Merk op dat er geen lag/lead-functies zijn in MySQL. Het enige dat u kunt doen, is variabelen gebruiken. De SELECT
clausule wordt regel voor regel verwerkt. U kunt dus de waarde van de huidige rij toewijzen in de laatste regels van de SELECT
clausule en gebruik daarom deze variabele als de waarde van "de vorige rij" in de eerste regels van de SELECT
clausule.
Houd er rekening mee dat de ORDER BY
is zeer belangrijk. Een tabel is niet gesorteerd. Gegevens in een relationeel DBMS worden niet gesorteerd, tenzij u een volgorde opgeeft met de ORDER BY
clausule.
- lees meer over het gebruik van variabelen in zoekopdrachten hier
BEWERKEN:
Verander het in
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;