Ini lebih baik dilakukan di tingkat aplikasi, tetapi hanya untuk bersenang-senang, ini dia di tingkat basis data:
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`
- lihat ini bekerja langsung di sqlfiddle
Perhatikan, bahwa tidak ada fungsi lag/lead di MySQL. Yang dapat Anda lakukan, adalah menggunakan variabel. SELECT
klausa diproses satu baris pada satu waktu. Jadi, Anda dapat menetapkan nilai baris saat ini di baris terakhir SELECT
klausa dan karena itu gunakan variabel ini sebagai nilai "baris sebelumnya" di baris pertama SELECT
klausa.
Perhatikan juga, bahwa ORDER BY
sangat penting. Sebuah tabel tidak diurutkan. Data dalam DBMS relasional tidak diurutkan kecuali Anda menentukan urutan dengan ORDER BY
klausa.
- baca selengkapnya tentang menggunakan variabel dalam kueri di sini
EDIT:
Ubah ke
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;