sql >> Databasteknik >  >> RDS >> Mysql

MySQL lag/lead funktion?

Detta görs bättre på applikationsnivå, men bara för skojs skull, här är det på databasnivå:

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`

Observera att det inte finns några lag/lead-funktioner i MySQL. Allt du kan göra är att använda variabler. SELECT klausul bearbetas en rad i taget. Så du kan tilldela värdet för den aktuella raden på de sista raderna i SELECT och använd därför denna variabel som värdet på "föregående rad" på de första raderna i SELECT klausul.
Observera att ORDER BY är väldigt viktigt. En tabell är inte sorterad. Data i ett relationellt DBMS sorteras inte om du inte anger en beställning med ORDER BY klausul.

  • läs mer om hur du använder variabler i frågor här

EDIT:

Ändra det till

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;



  1. Oracle Motsvarar MySQL INSERT IGNORE?

  2. Trädvyskontroll Markera Lägg till Ta bort noder

  3. TimeZone-avvikelse i mysql och java

  4. En indexerad vybugg med skalära aggregat