我有一堆记录,每天的每一分钟都会插入一行。每行包含一个日期时间时间戳记(时间),一个值(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?
答案 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