【问题标题】:How to group data within a range of contigious timestamps如何在一系列连续时间戳内对数据进行分组
【发布时间】:2019-11-02 23:28:30
【问题描述】:

我有一个表格,由通过不确定的轮询过程收集的数据行组成。每行都有一个开始和结束时间戳,表示收集数据的时间段。在某些情况下,数据是连续收集的,在这种情况下,一行的时间戳将与下一行的开始时间戳具有相同的值。在其他情况下,一排和下一排之间存在时间中断。

例如,在下表中,第 1、2、3 和 4 行都是一个时间序列数据的一部分。第 5、6、7 和 8 行也是如此,第 9 行和第 10 行也是如此。在这两者之间是我没有数据的时间段。

Row  Start_Timestamp      End_Timestamp           Data_Item
---  ---------------      --------------          ---------
1    2019-08-12_22:07:53  2019-08-12_22:09:57     100      
2    2019-08-12_22:09:57  2019-08-12_22:12:01     203      
3    2019-08-12_22:12:01  2019-08-12_22:13:03     487      
4    2019-08-12_22:13:03  2019-08-12_22:16:19     113      
5    2019-08-12_22:24:34  2019-08-12_22:26:37     632      
6    2019-08-12_22:26:37  2019-08-12_22:27:40     532      
7    2019-08-12_22:27:40  2019-08-12_22:28:42     543      
8    2019-08-12_22:28:42  2019-08-12_22:31:57     142      
9    2019-08-13_19:56:06  2019-08-13_19:57:08     351      
10   2019-08-13_19:57:08  2019-08-13_19:58:10     982      

我想将这些连续的时间序列理想地分组如下:

Row  Series  Start_Timestamp      End_Timestamp           Data_Item   
---  ------  ---------------      --------------          -----------  
1    1       2019-08-12_22:07:53  2019-08-12_22:09:57     100
2    1       2019-08-12_22:09:57  2019-08-12_22:12:01     203
3    1       2019-08-12_22:12:01  2019-08-12_22:13:03     487
4    1       2019-08-12_22:13:03  2019-08-12_22:16:19     113
5    2       2019-08-12_22:24:34  2019-08-12_22:26:37     632
6    2       2019-08-12_22:26:37  2019-08-12_22:27:40     532
7    2       2019-08-12_22:27:40  2019-08-12_22:28:42     543
8    2       2019-08-12_22:28:42  2019-08-12_22:31:57     142
9    3       2019-08-13_19:56:06  2019-08-13_19:57:08     351
10   3       2019-08-13_19:57:08  2019-08-13_19:58:10     982

我是 SQL 新手,一直在努力解决这个问题。对于如何实现这一目标,我很感激任何见解或建议。

【问题讨论】:

  • 嗨@seanfir,请告诉我们您使用什么数据库,Oracle、SQLServer、MySQL 或其他什么?谢谢!另外,您说:“例如,在下表中,第 1、2、3 和 4 行都是一个时间序列数据的一部分” - 请您再解释一下,例如我们如何识别前 4 行是系列 1 的一部分?谢谢!
  • 我正在使用 Amazon 的 AWS Athena,它使用 Presto 和 ANSI SQL。如果您仔细查看我的表格,您会注意到第一个时间序列(第 1 行)从 2019-08-12_22:07:53 运行到 2019-08-12_22:09:57,第二个时间序列从 2019-08 运行-12_22:09:57 至 2019-08-12_22:12:01。因此,第二个时间序列的开始与第一个时间序列的结束完全相同(第 1 行的结束时间戳等于第 2 行的开始时间戳)。第 2 到 3 行和第 3 到 4 行也是如此。第 4 行和第 5 行之间存在时间中断,即第 4 行的 end_timestamp 不等于第 5 行的 start_timestamp..

标签: sql window-functions gaps-and-islands


【解决方案1】:

这是一个简化的间隙和孤岛问题。假设您的 RDBMS 支持窗口函数,您可以使用窗口总和来解决此问题。当记录的Start_Timestamp 与上一条记录的End_Timestamp 不同时,将启动一个新组:

select
    t.Row,
    sum(case when Start_Timestamp = lag_End_Timestamp then 0 else 1 end) 
        over(order by End_Timestamp) series,
    t.Start_Timestamp,
    t.End_Timestamp,
    t.Data_Item
from (
    select
        t.*,
        lag(End_Timestamp) over (order by End_Timestamp) lag_End_Timestamp
    from mytable t
) t

Demo on DB Fiddle

行 |系列 | Start_Timestamp | End_Timestamp |数据项 --: | -----: | :----------------- | :----------------- | --------: 1 | 1 | 2019-08-12 22:07:53 | 2019-08-12 22:09:57 | 100 2 | 1 | 2019-08-12 22:09:57 | 2019-08-12 22:12:01 | 203 3 | 1 | 2019-08-12 22:12:01 | 2019-08-12 22:13:03 | 487 4 | 1 | 2019-08-12 22:13:03 | 2019-08-12 22:16:19 | 113 5 | 2 | 2019-08-12 22:24:34 | 2019-08-12 22:26:37 | 632 6 | 2 | 2019-08-12 22:26:37 | 2019-08-12 22:27:40 | 532 7 | 2 | 2019-08-12 22:27:40 | 2019-08-12 22:28:42 | 543 8 | 2 | 2019-08-12 22:28:42 | 2019-08-12 22:31:57 | 142 9 | 3 | 2019-08-13 19:56:06 | 2019-08-13 19:57:08 | 351 10 | 3 | 2019-08-13 19:57:08 | 2019-08-13 19:58:10 | 982

【讨论】:

  • 谢谢。这很清楚,对我来说效果很好。
猜你喜欢
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
相关资源
最近更新 更多