MySQL时间序列操作
我在5.6版中使用MySQL。(由于不存在可用的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
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 ""