SQL Group By在一定时间内

时间:2018-11-13 10:36:07

标签: sql

我需要按ID,状态和时间戳分组。

例如,我有此表:

id    | status | time   | value | deviceId
1     |  true  | 10:31  |   1   |      5 
2     |  true  | 10:32  |   2   |     5 
3     |  true  | 10:33  |   3   |     5
4     |  false | 10:34  |   3   |    5 
5     |  false | 10:35  |   4   |   5 
6     |  false | 10:36  |   5   |    5 
7     |  true  | 10:37  |   4   |    5
8     |  true  | 10:38  |   5   |    5
9     |  true  | 10:39  |   6   |  5

表是按时间排序的。

每个组都应具有相同的ID,如果状态为true,则在状态为true的时间内。

对于相同的groupId,当状态变为true时,我将需要新的结果,但这是在另一个时间范围内,因此应该是另一个组。

基于上述示例结果应为:

deviceId  | avg(value)
5 | 2 (average value for rows 1,2,3 for deviceid = 5)
5 | 5       (average value of rows 7,8,9 for deviceid = 5. Same group, but another time frame)

我可以按deviceId分组,也可以按状态分组。

SELECT  deviceid ,status, AVG(value)
FROM mytable
WHERE status = true
GROUP BY deviceid,status;

但是我不知道如何在时间范围内完成所有这些工作? 谢谢您的帮助。

编辑:

我试图解释什么是时间范围。也许我的英语不够好,所以我会再试一次。您可以看到时间到了。表按时间排序。

行1,2,3在时间范围内,而状态i为true。

第4行中的状态为false,因此这是第二个时间范围开始的时间。 第二个时间范围是第4、5、6行。

在第7行中,状态再次为true,因此在此开始第三时间范围。第三个时间范围是第7、8、9行

我只需要状态为true的组的结果,因此只有第一时间段和第三时间段与我相关。

1 个答案:

答案 0 :(得分:2)

您可以通过累计“假”来确定“真”的组。对于一组连续的“ true”,此计数将是恒定的。

其余的只是过滤和聚合:

select deviceid, grp, avg(value)
from (select t.*,
             sum(case when status = 'false' then 1 else 0 end) over (partition by deviceid order by time) as grp
      from t
     ) t
where status = 'true'
group by deviceid, grp;