MYSQL:查找连续计数的开始和结束时间戳

时间:2014-03-14 13:54:34

标签: mysql

我希望输出一系列正数的开始和结束时间

例如;我有下面的表有两列Timestamp和Marker.Marker由一系列的1和0组成:

我希望计算每个系列/ 1的运行次数,并在系列开始和结束时生成时间戳

Time_stamp                 Marker

2012-01-01 00:01:00         1

2012-01-01 00:02:10         1

2012-01-01 00:03:01         1

2012-01-01 00:04:15         0

2012-01-01 00:05:12         0

2012-01-01 00:06:00         1

2012-01-01 00:07:02         1

2012-01-01 00:08:19         1

2012-01-01 00:09:11         1

2012-01-01 00:10:10         1

示例输出表将显示每次运行值的每个1节的计数以及值在0出现之前开始和结束的时间。

Output Table:

Total Count       Start Timestamp            End Timestamp

   3              2012-01-01 00:01:00       2012-01-01 00:03:01 


   5              2012-01-01 00:06:00      2012-01-01 00:10:10   

我已经启动了一些代码(创建了一个名为tbl的表),它给出了1的总数以及整体值的start和End。不完全是我需要的。

Select Consec,
SUM(IF(Consec = '1',1,0)) AS Total_Count,
Min(Time_stamp) AS Min_Timestamp,
Max(Time_stamp) AS Max_Timestamp
FROM(
SELECT 
  a.*, 
 @val:=0,
 @Zero:=0,
 IF (a.Marker=1,@val:=@val+1,@Zero) AS Consec
FROM tbl a
) a

我缺乏想法。任何人都有关于如何调整的任何想法,我可以识别值'1'的单独运行并输出每次运行的开始和结束时间戳。

干杯

2 个答案:

答案 0 :(得分:0)

一种方法是为每个运行/系列提供唯一索引,然后使用GROUP BY来获取开始和结束时间戳。

你走了:

SELECT COUNT(*), MIN(time_stamp) AS starttime, MAX(time_stamp) AS endtime
FROM (
  SELECT IF(@prev <> marker, @s:=@s+1, @s:=@s) AS `index`, 
    time_stamp, @prev:=marker marker
  FROM
    tbl, (SELECT @s:= 0, @prev:= -1) s
) tmp
WHERE marker = 1
GROUP BY `index`

工作小提琴:http://sqlfiddle.com/#!2/f5f19c/3

答案 1 :(得分:0)

对于像这样的问题,游标是解决本质上是程序性而非关系性问题的有效方法。

此代码创建一个游标,该游标遍历您选择的表,并在每次发现更改时写下来。

这样做的好处是不需要子查询,因此可以根据需要处理大的表。

    CREATE PROCEDURE markchange()
BEGIN    
DECLARE done INT DEFAULT FALSE;
DECLARE a,start_time DATETIME;
DECLARE b,marker,count INT;
DECLARE cur CURSOR FOR SELECT Time_stamp,Marker FROM targetTable
                       ORDER BY Time_stamp ASC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;     
OPEN cur;       
FETCH cur INTO a,b;
SET start_time = a;
SET end_time = a;
SET marker = b;
SET count = 0;
read_loop: LOOP
    FETCH cur INTO a,b;   
    IF done THEN
        INSERT INTO `Output Table` (count_col,start_time_col, end_time_col)
        VALUES (count,start_time, end_time);
        LEAVE read_loop;
    END IF;
    SET count = count + 1;
    SET end_time = a;
    IF marker <> b THEN
        INSERT INTO `Output Table` (count_col,start_time_col, end_time_col)
        VALUES (count,start_time, end_time);
        SET start_time = a;
        SET marker = b;
        SET count = 0;
    END IF;
END LOOP;           
CLOSE cur;      
END