2

我有一个带有日期戳的事件表,我想显示事件之间的时间间隔。例如,如果我有

event  |  datestamp
-------------------
  a    |   05:00
  b    |   07:00
  c    |   08:00
  d    |   12:00
 ...

我想写一个简单的查询给我

event  |  datestamp  |  last | since_last
-----------------------------------------
  a    |   05:00     |  NULL |  NULL
  b    |   07:00     |   a   |  2 hours
  c    |   08:00     |   b   |  1 hour
  d    |   12:00     |   c   |  4 hours

最后一列的格式并不重要——它可以是毫秒、秒、人类可读的东西,任何简单的东西。另请注意,实际数据具有正确的日期时间,我只是懒得输入日期。

重要的部分是“b”的记录中没有任何内容指向“a”作为前一个事件,所以像这个问题这样的解决方案不起作用——我需要一些语法来选择所有已加入的记录到最近的旧记录。

我尝试过的看起来像

SELECT new.event, new.datestamp, old.event AS last,
    TIMESTAMPDIFF(SECOND, MAX(old.datestamp), new.datestamp) AS since_last
FROM events AS new, events AS old
WHERE new.datestamp > old.datestamp
LIMIT 10;

但它似乎只是挂起——我让它运行了一分钟多。根据这个问题,我试过了

SELECT event, datestamp,
  (SELECT MAX(old.datestamp)
   FROM events old
   WHERE new.datestamp > old.datestamp
  ) last_ds
FROM events new
LIMIT 10;

这实际上有效,但在我的表上需要超过 14 秒的一百万个事件,即使我只选择 10 条记录,所以一定有问题。

4

2 回答 2

3

尝试使用

select event,datestamp,
       @PrevEvent as last,  
       TIMESTAMPDIFF(SECOND, @PrevDate, datestamp) AS since_last,
       @PrevDate:=datestamp,
       @PrevEvent:=event
from events, (select @PrevDate:=null,@PrevEvent:=null) t
order by datestamp

SQLFiddle 演示

要选择最后 10 个事件,只需使用带有 LIMIT 的子查询,而不仅仅是events表。

select event,datestamp,
       @PrevEvent as last,  
       TIMESTAMPDIFF(SECOND, @PrevDate, datestamp) AS since_last,
       @PrevDate:=datestamp,
       @PrevEvent:=event
from ( select *
       from events
       order by datestamp DESC
       LIMIT 10
     ) t1, (select @PrevDate:=null,@PrevEvent:=null) t
order by datestamp

升级版:

要在最近的 10 中获得正确的第一行(不是 NULL since_last 字段),您应该首先在内部子查询中限制 11 (10+1),然后在外部查询LIMIT 10 OFFSET 1中。

select event,datestamp,last,since_last
FROM
(
select event,datestamp,
       @PrevEvent as last,  
       TIMESTAMPDIFF(SECOND, @PrevDate, datestamp) AS since_last,
       @PrevDate:=datestamp,
       @PrevEvent:=event
from ( select *
       from events
       order by datestamp DESC
       LIMIT 11
     ) t1, (select @PrevDate:=null,@PrevEvent:=null) t
order by datestamp
) t3 
LIMIT 10 offset 1
于 2013-08-16T11:58:38.713 回答
1
Select event,datestamp,last,since_last FROM
(select event,datestamp,
       @PrevEvent as last,  
       concat((TIMESTAMPDIFF(SECOND, @PrevDate, datestamp))/3600,
              ' Hours') AS since_last,
       @PrevDate:=datestamp,
       @PrevEvent:=event
from events, (select @PrevDate:=null,@PrevEvent:=null) t
order by datestamp) abc

小提琴

于 2013-08-16T12:11:36.867 回答