2013-02-27 57 views
0

我有一个表,其中列出了某些对象的事件。查找MySQL数据库中不同行中时间戳之间的重叠,按天数和ID分组

有两个事件:“移动”和“加载”。他们可以开始和结束,而这些事件发生时会列出时间戳。

用下面的要求,我可以得到以下值:

sum of time, when movement took place (value in the fiddle: 421) 
sum of time, when load took place (value in the fiddle: 520) 
sum of time, when movement and load took place (value in the fiddle: 391) 

当前版本的每一天计算这些数字,这工作正常。

http://sqlfiddle.com/#!2/518dd/1

,但我也将有不同的ID。我现在要计算每个日期和每个ID的这些数字。当我加入这个数据,它崩溃,看到这个小提琴:

http://sqlfiddle.com/#!2/b43fa/6

这不是重复这个问题:Find intersections between rows and timestamps in a mysql db,因为解决这个问题是不适合/适应在这种情况下。

+1

你已经问过这个问题。 http://stackoverflow.com/questions/15112004/find-intersections-between-rows-and-timestamps-in-a-mysql-db/15112934#15112934 – Meherzad 2013-02-27 14:44:44

+1

为什么你创建了另一个问题? – 2013-02-27 14:44:45

+2

@BenjaminM。 。 。显然,他提出了另一个问题,因为第一个问题的接受答案不容易推广到用'id'和日期进行分组。他并没有使这个问题失效,而是选择了(我认为合理的)提出另一个问题。 – 2013-02-27 14:52:16

回答

2

如图所示由Gordon,分组通过移动成为可能过滤到最外面的SELECT。 对于需要封闭运动事件的加载事件的搜索是在相同的方式完成在earlier answer

SELECT id, 
     date(timestamp, 'unixepoch') AS date, 
     (SUM(CASE WHEN event = 'movement end' THEN timestamp END) - 
     SUM(CASE WHEN event = 'movement start' THEN timestamp END) 
     ) AS all_movement, 
     (SUM(CASE WHEN event = 'load end' THEN timestamp END) - 
     SUM(CASE WHEN event = 'load start' THEN timestamp END) 
     ) AS all_load, 
     (SUM(CASE WHEN event = 'movement end' AND 
         (SELECT event 
         FROM Table1 b 
         WHERE timestamp = (SELECT MIN(timestamp) 
              FROM Table1 c 
              WHERE c.timestamp >= a.timestamp 
              AND c.id = a.id 
              AND c.event LIKE 'load %') 
         AND b.id = a.id 
         AND b.event LIKE 'load %' 
        ) = 'load end' 
      THEN timestamp END) - 
     SUM(CASE WHEN event = 'movement start' AND 
         (SELECT event 
         FROM Table1 b 
         WHERE timestamp = (SELECT MAX(timestamp) 
              FROM Table1 c 
              WHERE c.timestamp <= a.timestamp 
              AND c.id = a.id 
              AND c.event LIKE 'load %') 
         AND b.id = a.id 
         AND b.event LIKE 'load %' 
        ) = 'load start' 
      THEN timestamp END) 
     ) AS load_movement 
FROM Table1 a 
GROUP BY id, 
     date(timestamp, 'unixepoch') 
+0

嗨,谢谢你的回答,但是我不能让它在小提琴里工作,即使我用'DATE(FROM_UNIXTIME(timestamp))'替换'date(timestamp,'unixepoch')''。请参阅小提琴:http://sqlfiddle.com/#!2/b43fa/6 – 2013-02-27 21:47:02

+0

您的解决方案非常完美,适用于不同的日子。但是,如果有与另一个ID(rowID为41-48的行)相同时间戳的其他ID的条目,则会产生一个错误:http://sqlfiddle.com/#!2/a1baa/1。所有其他的事情在这个查询中都很完美。 – 2013-03-02 12:32:57

+1

已更新。另外,具有相同时间戳的'运动'事件也可能导致同样的问题。 – 2013-03-02 13:21:29

2

问题是您开始的查询。我根本不明白第三栏是什么。但是,前两个是多使用更容易地计算出:

select (sum(case when event = 'movement end' then timestamp end) - 
     sum(case when event = 'movement start' then timestamp end) 
     ), 
     (sum(case when event = 'load end' then timestamp end) - 
     sum(case when event = 'load start' then timestamp end) 
     ) 
from table1 

由此看来,它应该是微不足道通过添加的组:

select id, date(timestamp), 
     (sum(case when event = 'movement end' then timestamp end) - 
     sum(case when event = 'movement start' then timestamp end) 
     ), 
     (sum(case when event = 'load end' then timestamp end) - 
     sum(case when event = 'load start' then timestamp end) 
     ) 
from table1 
group by id, date(timestamp) 
+0

第三行显示的时间量,移动发生的地方和负载发生......很难解释 – 2013-02-27 14:55:19

+1

@MichaelMeier。 。 。你在第一个问题上接受了很差的答案。它正在引导你找出你想要的痛苦的路径。 – 2013-02-27 14:56:09

+0

下面是一个示例:在第1到第4行中,没有关于135150800和1351508020范围内的负载的信息。负载信息从13行1351508080开始。因此,“20无负载”和“10无负载”不应该是用于“移动时间(负载)”的计算。是否允许我重新打开其他问题? – 2013-02-27 15:02:07

相关问题