MySQL计数1到0为止的连续值数

时间:2018-07-11 01:50:22

标签: mysql count break

我有一堆记录,每天的每一分钟都会插入一行。每行包含一个日期时间时间戳记(时间),一个值(0或1)和一个外键spotID。总共有100个景点。

我需要查看从两个时间戳之间的顶部开始将值1保持多长时间:“ 2017-01-01 00:00:00”和“ 2017-01-01 00:05:00”( 5小时)。如果保持值为0,则计数器停止并移至下一个SpotID。

示例,这是我正在使用的当前查询,从理论上讲,最终查询应如何通过该查询:

SELECT time, value, spotID FROM `records` 
WHERE time BETWEEN '2017-01-01 00:00:00' AND '2017-01-01 05:00:00'
ORDER BY `spotID`, `time` DESC

+------------------------+----------------+-------------+
|    time (datetime)     | value (0 or 1) | spotID (fk) |
+------------------------+----------------+-------------+
| '2017-01-01 05:59:00'  |              1 |           1 |
| '2017-01-01 05:58:00'  |              1 |           1 |
| '2017-01-01 05:57:00'  |              1 |           1 |
| ...consecutive 1's...                                 |
| '2017-01-01 05:30:00'  |              1 |           1 |
| '2017-01-01 05:29:00'  |              0 |           1 |
| ...we hit 0, count 1's and move onto spotID 2...      |
| '2017-01-01 05:59:00'  |              1 |           2 |
| '2017-01-01 05:58:00'  |              1 |           2 |
| '2017-01-01 05:57:00'  |              1 |           2 |
| '2017-01-01 05:56:00'  |              1 |           2 |
| ...consecutive 1's...                                 |
| '2017-01-01 03:42:00'  |              1 |           2 |
| '2017-01-01 03:41:00'  |              0 |           2 |
| ...we hit 0, count 1's and move onto spotID 3...      |
| '2017-01-01 05:59:00'  |              0 |           3 |
| ...we hit 0, count 1's and move onto spotID 4...      |
+------------------------+----------------+-------------+

最终查询应显示(如果我的数学正确):

+--------+---------+
| spotID | minutes |
+--------+---------+
|     1  |      29 |
|     2  |     137 |
|     3  |       0 |
|    ..  |      .. |
|   100  |      .. |
+--------+---------+

我只是不确定如何遍历上面的查询并计算连续的1的总和,直到到达第一个0(忽略之后的任何1,而直接移至下一个spotID)。

编辑:

这是我当前的查询:

SELECT a.spotID, SUM(a.value) as minutes
FROM (

    SELECT sr.time, sr.value, sr.spotID FROM `records` as sr
    WHERE sr.time BETWEEN '2017-01-01 00:00:00' AND '2017-01-01 05:00:00'
    ORDER BY sr.spotID, sr.time DESC

) a

GROUP BY a.spotID

但是,它非常接近,我仍然不知道如何获取它以排除值0之后的任何行。我想知道是否需要在CUM中放入CASE?

2 个答案:

答案 0 :(得分:0)

如果每分钟插入每一行,为什么不只计算每个spotID的行数。

SELECT time,a.spotID,minutes FROM records as a
INNER JOIN (
  SELECT spotID,COUNT(spotID) as minutes FROM records
  WHERE time > [MIN TIME] AND time < [MAX TIME]
  GROUP BY id
  ) b ON a.spotID = b.spotID
WHERE time > [MIN TIME] AND time < [MAX TIME]
ORDER BY time DESC

喜欢吗?由于我只是使用SQL提琴,因此不确定是否会运行。

答案 1 :(得分:0)

我将分两步完成。

这是我的解决方法:

创建数据:

DROP TABLE IF EXISTS bleach;
CREATE TABLE `bleach` (`time` DATETIME, `value` INT, spotID INT);

INSERT INTO bleach (`time`, `value`,spotID) SELECT '2017-01-01 05:59:00',1,1;
INSERT INTO bleach (`time`, `value`,spotID) SELECT '2017-01-01 05:58:00',1,1;
INSERT INTO bleach (`time`, `value`,spotID) SELECT '2017-01-01 05:57:00',1,1;
INSERT INTO bleach (`time`, `value`,spotID) SELECT '2017-01-01 05:30:00',1,1;
INSERT INTO bleach (`time`, `value`,spotID) SELECT '2017-01-01 05:29:00',0,1;

创建临时表并根据Spotid插入

DROP TABLE IF EXISTS bleach2;
CREATE TABLE bleach2 (min_time DATETIME, max_time DATETIME, spotid INT, minutes TIME);

INSERT INTO bleach2 (min_time, max_time, spotID) SELECT MIN(`time`), MAX(`time`), spotID FROM bleach WHERE `value`=1 GROUP BY spotID;

计算时差:

UPDATE bleach2 SET minutes=TIMEDIFF(min_time,max_time);

输出

min_time             max_time             spotid     minutes

2017-01-01 05:30:00 2017-01-01 05:59:00    1        -00:29:00