Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Lag/Lead-Funktion?

Dies geschieht besser auf Anwendungsebene, aber nur zum Spaß, hier ist es auf Datenbankebene:

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`

Beachten Sie, dass es in MySQL keine Lag/Lead-Funktionen gibt. Alles, was Sie tun können, ist, Variablen zu verwenden. Die SELECT -Klausel wird zeilenweise verarbeitet. So können Sie in den letzten Zeilen des SELECT den Wert der aktuellen Zeile zuweisen -Klausel und verwenden Sie daher diese Variable als Wert der "vorherigen Zeile" in den ersten Zeilen des SELECT -Klausel.
Beachten Sie auch, dass die ORDER BY ist sehr wichtig. Eine Tabelle ist nicht sortiert. Daten in einem relationalen DBMS werden nicht sortiert, es sei denn, Sie geben eine Reihenfolge mit dem ORDER BY an Klausel.

  • Lesen Sie mehr über die Verwendung von Variablen in Abfragen hier

BEARBEITEN:

Ändern Sie es 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;