MySQL时间序列操作

MySQL时间序列操作,mysql,time-series,Mysql,Time Series,我在5.6版中使用MySQL。(由于不存在可用的mysql函数而提及) 给定一个带有“运动检测”时间戳的表。每行检测到一个运动。没有动议就意味着没有进入 Id | Date Time --------------- 1 | 2018-01-01 15:00:01 // Start of activity phase 1 2 | 2018-01-01 15:00:03 3 | 2018-01-01 15:00:06 // Stop of activity phase 1 // Non-A

我在5.6版中使用MySQL。(由于不存在可用的mysql函数而提及)

给定一个带有“运动检测”时间戳的表。每行检测到一个运动。没有动议就意味着没有进入

Id | Date Time
---------------
1  | 2018-01-01 15:00:01  // Start of activity phase 1
2  | 2018-01-01 15:00:03
3  | 2018-01-01 15:00:06  // Stop of activity phase 1
// Non-Activity phase
4  | 2018-01-01 17:01:06  // Start of activity phase 2
5  | 2018-01-01 17:02:06
6  | 2018-01-01 17:02:09  // Stop of activity phase 2
// Non-Activity phase, big one because of holiday
7  | 2018-01-10 19:40:06  // Start of activity phase 3
8  | 2018-01-10 19:41:06  // Stop of activity phase 3
我很难找到一个SQL查询,它可以让我概括“活动阶段”

我想得到的是:

Id | Activity starts     | Activity ends
---------------------------------------------
1  | 2018-01-01 15:00:01 | 2018-01-01 15:00:06
2  | 2018-01-01 17:01:06 | 2018-01-01 17:02:09
3  | 2018-01-10 19:40:06 | 2018-01-10 19:41:06
我想查看“活动阶段”的开始和结束时间戳。 “活动阶段”的定义:“活动阶段”位于至少30分钟的两个“非活动阶段”之间


先谢谢你

我认为在MySQL 5.6中实现这一点的唯一方法是使用存储过程(尽管我希望看到有人证明我错了)。这个可以做你想做的。请注意,它返回许多单行结果集,因此需要在应用程序框架中处理这些结果集。或者,您可以修改过程,将中间结果存储到临时表中,然后在过程结束时从临时表中选择所有内容(请参见下文)

对于示例数据,此过程将返回:

activity_count  start                   end     
1               2018-01-01 15:00:01     2018-01-01 15:00:06
activity_count  start                   end     
2               2018-01-01 17:01:06     2018-01-01 17:02:09
activity_count  start                   end     
3               2018-01-10 19:40:06     2018-01-10 19:41:06
以下是使用临时表的过程:

DELIMITER //
DROP PROCEDURE IF EXISTS get_activity //
CREATE PROCEDURE get_activity()
BEGIN
  DECLARE start, thistime, lasttime DATETIME;
  DECLARE activity_count INT DEFAULT 1;
  DECLARE finished INT DEFAULT 0;
  DECLARE activity_cursor CURSOR FOR SELECT atime FROM activity;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
  CREATE TEMPORARY TABLE activity_temp (id INT, start DATETIME, end DATETIME);
  OPEN activity_cursor;
  FETCH activity_cursor INTO start;
  SET lasttime = start;
  act_loop: LOOP
    FETCH activity_cursor INTO thistime;
    IF finished = 1 THEN
      INSERT INTO activity_temp VALUES (activity_count, start, lasttime);
      LEAVE act_loop;
    END IF;
    IF thistime > lasttime + INTERVAL 30 MINUTE THEN
      INSERT INTO activity_temp VALUES (activity_count, start, lasttime);
      SET start = thistime;
      SET activity_count = activity_count + 1;
    END IF;
    SET lasttime = thistime;
  END LOOP;
  SELECT * FROM activity_temp;
  DROP TABLE activity_temp;
END //
输出(从
调用get\u activity()
):


尽管@Nick给出了有效的答案,我还是花了几个小时找到了以下解决方案:

SET @row_number = 0;
SET @row_number2 = 0;
SET @gap_time = "00:30:00";
Select
  "",
  DAYNAME(prep1.datetime2) "Weekday",
  prep1.datetime2 "Activity starts",
  prep2.datetime1 "Activity ends"

FROM

(SELECT
 (@row_number:=@row_number + 1) AS num
 ,detection1.id id1
 ,detection1.insert_datetime datetime1
 ,detection2.id id2
 ,detection2.insert_datetime datetime2
 ,timediff(detection2.insert_datetime,detection1.insert_datetime) as diff
FROM
 MOVEMENT_TRACKING detection1,
 MOVEMENT_TRACKING detection2
WHERE
 detection1.id + 1 = detection2.id
 and timediff(detection2.insert_datetime,detection1.insert_datetime)  > @gap_time
order by detection1.id) as prep1,

(SELECT
 (@row_number2:=@row_number2 + 1) AS num
 ,detection1.id id1
 ,detection1.insert_datetime datetime1
 ,detection2.id id2
 ,detection2.insert_datetime datetime2
 ,timediff(detection2.insert_datetime,detection1.insert_datetime) as diff
FROM
 MOVEMENT_TRACKING detection1,
 MOVEMENT_TRACKING detection2
WHERE
 detection1.id + 1 = detection2.id
 and timediff(detection2.insert_datetime,detection1.insert_datetime)  > @gap_time
order by detection1.id) as prep2

WHERE
 prep1.num + 1 = prep2.num
ORDER BY
 prep1.datetime2 DESC
由于调试的原因,我让他们加入了,一些减少仍然是可能的。需要一些黑客,比如

Select "" 

由于数据库承载安全策略规则。

我可以在哪里读取链接到id/date-time的activy阶段?您好,我所有的数据都如清单1所示,我寻找一个产生如清单2所示内容的查询。在您的列表1中,只有关于activy阶段的信息是您的注释。你无法用这些数据达到你的目标。再次感谢,我认为这个问题没有被理解或解释得很糟糕。谈到清单1:ID 3和4之间没有其他行。因此,在2018-01-01 15:00:06和2018-01-01 17:01:06之间,未检测到任何运动。这是一个非活动阶段,因为它超过30分钟。活动阶段是指不包含(行:行+1)>=30分钟的所有内容。感谢您的详细回答,我将在接下来的10小时内尝试。这看起来像我最初走的路径。当在一个活动阶段检测到4个或更多动作时,我无法使其工作。你的查询看起来也不一样?啊,谢谢,上下限有一些问题。没有意识到这一点,但不确定在现实生活中有多大影响。奇怪,你的SQLFiddle工作了四年而我的却没有。。。尽管正如你所说,它缺少第一个和最后一个条目。在一张大桌子上看到这两种方法之间的速度差异会很有趣;我可以看到3个交叉连接变得非常昂贵。
SET @row_number = 0;
SET @row_number2 = 0;
SET @gap_time = "00:30:00";
Select
  "",
  DAYNAME(prep1.datetime2) "Weekday",
  prep1.datetime2 "Activity starts",
  prep2.datetime1 "Activity ends"

FROM

(SELECT
 (@row_number:=@row_number + 1) AS num
 ,detection1.id id1
 ,detection1.insert_datetime datetime1
 ,detection2.id id2
 ,detection2.insert_datetime datetime2
 ,timediff(detection2.insert_datetime,detection1.insert_datetime) as diff
FROM
 MOVEMENT_TRACKING detection1,
 MOVEMENT_TRACKING detection2
WHERE
 detection1.id + 1 = detection2.id
 and timediff(detection2.insert_datetime,detection1.insert_datetime)  > @gap_time
order by detection1.id) as prep1,

(SELECT
 (@row_number2:=@row_number2 + 1) AS num
 ,detection1.id id1
 ,detection1.insert_datetime datetime1
 ,detection2.id id2
 ,detection2.insert_datetime datetime2
 ,timediff(detection2.insert_datetime,detection1.insert_datetime) as diff
FROM
 MOVEMENT_TRACKING detection1,
 MOVEMENT_TRACKING detection2
WHERE
 detection1.id + 1 = detection2.id
 and timediff(detection2.insert_datetime,detection1.insert_datetime)  > @gap_time
order by detection1.id) as prep2

WHERE
 prep1.num + 1 = prep2.num
ORDER BY
 prep1.datetime2 DESC
Select ""