【问题标题】:SQL Group By within some time frameSQL Group By 在某个时间范围内
【发布时间】:2018-11-13 10:36:06
【问题描述】:

我需要按 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,如果状态为真,则在一段时间内状态为真。

对于相同的 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 为真。

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

在第 7 行,状态再次为真,因此第三时间框架从这里开始。第三个时间框架是第 7、8、9 行

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

【问题讨论】:

  • 1,2,3 和 7,8,9 是行,而不是列。另外,请定义您的时间范围。我只是看到了一堆不同的时间,我看不出它们中的一些如何属于一起而另一些不属于。
  • 时间列的类型是什么?
  • @majidarif 时间戳
  • 时间不能硬编码。它应该适用于任何时间范围。我可以有 1000 个时间框架。
  • SQL 只是一种语言,您使用的是什么 rdbms?请edit您的问题包括 rdbms 产品标签以及特定版本标签。

标签: sql


【解决方案1】:

您可以通过“假”的累积计数来确定“真”的组。对于一组连续的“真”,此计数将保持不变。

剩下的就是过滤和聚合:

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;

【讨论】:

    猜你喜欢
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多