Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Função lag/lead do MySQL?


Isso é melhor feito no nível do aplicativo, mas apenas por diversão, aqui está no nível do banco de dados:
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`

Observe que não há funções lag/lead no MySQL. Tudo o que você pode fazer é usar variáveis. O SELECT cláusula é processada uma linha por vez. Então você pode atribuir o valor da linha atual nas últimas linhas do SELECT cláusula e, portanto, use esta variável como o valor da "linha anterior" nas primeiras linhas do SELECT cláusula.
Observe também que o ORDER BY é muito importante. Uma tabela não está classificada. Os dados em um DBMS relacional não são classificados, a menos que você especifique um pedido com o ORDER BY cláusula.
  • leia mais sobre como usar variáveis ​​em consultas aqui

EDITAR:

Altere para
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;