これはアプリケーションレベルで行う方が適切ですが、楽しみのために、ここではデータベースレベルで行います:
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`
- sqlfiddle でライブで動作することを確認してください
MySQLにはラグ/リード関数がないことに注意してください。できることは、変数を使用することだけです。 SELECT
句は一度に1行ずつ処理されます。したがって、SELECT
の最後の行で現在の行の値を割り当てることができます。 したがって、この変数をSELECT
の最初の行の「前の行」の値として使用します。 条項。
また、ORDER BY
にも注意してください。 はとても重要です。テーブルはソートされません。 ORDER BY
で順序を指定しない限り、リレーショナルDBMSのデータはソートされません。 条項。
- クエリでの変数の使用について詳しくは、こちらをご覧ください
編集:
に変更
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;