【问题标题】:MySQL lag/lead function?MySQL滞后/领先功能?
【发布时间】:2015-04-10 07:50:43
【问题描述】:

我想计算上一个会话的用户开始时间和停止时间之间的差异..

表包含:用户数字、开始/停止 unix 时间戳。它在用户和启动之后排序

user  start   stop
1    150000 150010
1    160011 160050
1    160100 160200
2    150011 150023
2    155001 155055
2    160001 160500
3    159001 159550

我希望结果看起来像:

user start   stop  diff
1   150000 150010  160011-150010=10001
1   160011 160050  160100-160050
1   160100 160200  0 (new user on next row)
2   150011 150023  155001-150023
2   155001 155055  160001-155055
2   160001 160500  0 (new user on next row)
3   159001 159550  and so on..

是否有可能做到这一点,如果可以,怎么做?

【问题讨论】:

  • 我敢打赌,这里的业务逻辑存在缺陷。为什么用户不会因为下一行有另一个用户而有时间差?另外,我们能否确定表格是按用户 ID 和开始日期排序的?
  • 我无法创造任何有用的东西。忘记写了,但是是的,表格是在用户和启动之后排序的!我只看用户的差异,而不是用户的差异!奥克
  • 如果我正确理解您的数据,那么每一行的差异就是同一用户的时间差异。不涉及其他用户。特别是因为它们的时间间隔在某些情况下会重叠。
  • 没错!就像我上面说的,数据在用户和启动之后排序。所以对于上面的例子,用户 1 只有 3 个会话,用户 2 在表中只有 3 个会话..
  • 仅供参考,Ake 和 @ytg,数据未在关系 DBMS 中排序。绝不。这就是ORDER BY 子句的用途。如果不指定,则无法确定每次执行查询时都以相同的顺序返回数据。

标签: mysql


【解决方案1】:

这在应用程序级别做得更好,但只是为了好玩,这里是在数据库级别:

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 子句一次处理一行。因此,您可以在SELECT 子句的最后几行中分配当前行的值,从而将此变量用作SELECT 子句的第一行中“上一行”的值。
另请注意,ORDER BY 非常重要。表未排序。除非您使用 ORDER BY 子句指定顺序,否则不会对关系 DBMS 中的数据进行排序。

  • 阅读更多关于在查询中使用变量here

编辑:

改成

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;

【讨论】:

    猜你喜欢
    • 2022-06-23
    • 1970-01-01
    • 2013-09-25
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    • 2019-01-30
    相关资源
    最近更新 更多