如何在一系列连续的时间戳内对数据进行分组



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

例如,在下表中,第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的新手,一直在努力解决这个问题。我很感激任何关于我如何实现这一目标的见解或建议。

这是一个简化的间隙和孤岛问题。假设您的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

DB Fiddle上的演示

行|系列|开始时间戳|结束时间戳|数据项--:|-----:|:------------------|:------------------|--------:1|1|2019-08-12 22:07:53|2019-08-22 22:09:57|1002|1 | 2019-08-12 22:09:57 | 2019-08-22 22:12:01 | 2033|1 | 2019-08-12 22:12:01 | 2019-08-22 22:13:03 | 4874|1 | 2019-08-12 22:13:03 | 2019-08-22 22:16:19 | 1135|2|2019-08-12 22:24:34|2019-08-22 22:26:37|6326|2|2019-08-12 22:26:37|2019-08-22 22:27:40|5327 | 2 | 2019-08-12 22:27:40 | 2019-08-22 22:28:42 | 5438 | 2 | 2019-08-12 22:28:42 | 2019-08-12 22:31:57 | 1429 | 3 | 2019-08-13 19:56:06 | 2019-08-23 19:57:08 | 35110 | 3 | 2019-08-13 19:57:08 | 2019-08-23 19:58:10 | 982

最新更新