如何在一系列连续的时间戳中对数据进行分组
How to group data within a range of contigious timestamps
我有一个 table 由通过不确定的轮询过程收集的数据行组成。每行都有一个开始和结束时间戳,表示收集数据的时间段。在某些情况下,数据是连续收集的,在这种情况下,一行的时间戳将与下一行的开始时间戳具有相同的值。在其他情况下,一行和下一行之间存在时间中断。
例如,在下面的 table 中,第 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 支持 window 函数,您可以使用 window 求和来解决这个问题。当记录的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
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
我有一个 table 由通过不确定的轮询过程收集的数据行组成。每行都有一个开始和结束时间戳,表示收集数据的时间段。在某些情况下,数据是连续收集的,在这种情况下,一行的时间戳将与下一行的开始时间戳具有相同的值。在其他情况下,一行和下一行之间存在时间中断。
例如,在下面的 table 中,第 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 支持 window 函数,您可以使用 window 求和来解决这个问题。当记录的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
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