SQL查询以在一系列重叠(时间)间隔内查找非重叠间隔的子集
我有一系列可能重叠的编号时间间隔。重要提示:没有两个间隔同时开始,开始间隔的时间是严格意义上的 说明:SQL查询以在一系列重叠(时间)间隔内查找非重叠间隔的子集,sql,algorithm,google-bigquery,intervals,date-range,Sql,Algorithm,Google Bigquery,Intervals,Date Range,我有一系列可能重叠的编号时间间隔。重要提示:没有两个间隔同时开始,开始间隔的时间是严格意义上的 说明: Task 1: 1111111 Task 2: 22222222222 Task 3: 333333333333333 Task 4: 444444 Task 5: 5555555 Task 6: 66
Task 1: 1111111
Task 2: 22222222222
Task 3: 333333333333333
Task 4: 444444
Task 5: 5555555
Task 6: 66
.
.
.
0 --- time axis --->
Task 1: 1111111 (yes, first)
Task 2: ----------- (no, task 1 is running when 2 begins)
Task 3: 333333333333333 (yes)
Task 4: ------ (no, task 3 is running when 4 begins)
Task 5: ------- (no, task 3 is running when 5 begins)
Task 6: 66 (yes)
.
.
.
0 --- time axis --->
间隔代表应执行的任务。我正在寻找一个选择可以执行的任务的SQL查询,因为在一次只能执行一个任务。第一个任务总是要执行的。接下来,从第一个任务完成后开始的所有任务中,执行最早开始的任务。等等
结果:可以执行任务1、3和6。说明:
Task 1: 1111111
Task 2: 22222222222
Task 3: 333333333333333
Task 4: 444444
Task 5: 5555555
Task 6: 66
.
.
.
0 --- time axis --->
Task 1: 1111111 (yes, first)
Task 2: ----------- (no, task 1 is running when 2 begins)
Task 3: 333333333333333 (yes)
Task 4: ------ (no, task 3 is running when 4 begins)
Task 5: ------- (no, task 3 is running when 5 begins)
Task 6: 66 (yes)
.
.
.
0 --- time axis --->
使用迭代,算法很简单:在一个循环中,以升序在区间上迭代,记住最后一个选定区间的结束。但是,我想请您提供一个SQL查询,可能使用窗口函数,可以在Google BigQuery上执行
任务表的架构:
task_id: integer,
start_timestamp: integer,
duration_seconds: integer.
样本数据:
task_id,start_timestamp,duration_seconds
1,1,7
2,4,11
3,12,15
4,16,6
5,24,7
6,33,2
7,37,4
8,42,13
9,47,3
10,50,2
11,54,21
12,58,14
13,66,8
14,72,7
15,80,6
16,88,16
17,92,14
18,102,3
19,109,2
20,119,10
21,123,13
22,128,21
23,138,7
24,141,17
25,146,9
26,154,17
27,160,17
28,164,13
29,173,21
30,181,7
结果-所选任务:
1,3,6,7,8,12,14,15,16,19,20,23,25,27,30
样本数据说明:
Task 1: 1111111
Task 2: 22222222222
Task 3: 333333333333333
Task 4: 444444
Task 5: 5555555
Task 6: 66
Task 7: 7777
Task 8: 8888888888888
Task 9: 999
Task 10: 10
Task 11: 11xxxxxxxxxxxxxxxxxxx
Task 12: 12xxxxxxxxxxxx
Task 13: 13xxxxxx
Task 14: 14xxxxx
Task 15: 15xxxx
Task 16: 16xxxxxxxxxxxxxx
Task 17: 17xxxxxxxxxxxx
Task 18: 18x
Task 19: 19
Task 20: 20xxxxxxxx
Task 21: 21xxxxxxxxxxx
Task 22: 22xxxxxxxxxxxxxxxxxxx
Task 23: 23xxxxx
Task 24: 24xxxxxxxxxxxxxxx
Task 25: 25xxxxxxx
Task 26: 26xxxxxxxxxxxxxxx
Task 27: 27xxxxxxxxxxxxxxx
Task 28: 28xxxxxxxxxxx
Task 29: 29xxxxxxxxxxxxxxxxxxx
Task 30: 30xxxxx
任务1:1111111
任务2:22222
任务3:333
任务4:4444
任务5:555
任务6:66
任务7:7777
任务8:88888888888
任务9:999
任务10:10
任务11:11xxxxxxxxxxxx
任务12:12XXXXXXXXXX
任务13:13xxxxxx
任务14:14xxxxx
任务15:15xxxx
任务16:16XXXXXXXXXXXXX
任务17:17XXXXXXXXXX
任务18:18x
任务19:19
任务20:20xxxxxxxx
任务21:21XXXXXXXXXX
任务22:22xxxxxxxxxxxxxxxx
任务23:23xxxxx
任务24:24xxxxxxxxxxxxx
任务25:25xxxxxxx
任务26:26xxxxxxxxxxxxx
任务27:27xxxxxxxxxxxxx
任务28:28XXXXXXXXXX
任务29:29xxxxxxxxxxxx
任务30:30xxxxx
非常感谢您的帮助。一种方法如下: 查找重叠的任务(开始时间介于其他任务的开始时间和结束时间之间),然后提取所有其他任务
Select task_id
FROM [table]
where Task_id not in(
Select B.task_id FROM
(SELECT task_id, start_timestamp, duration_seconds ,start_timestamp+duration_seconds as end_timestamp
FROM [table] ) as A
CROSS JOIN EACH
(SELECT task_id, start_timestamp, duration_seconds ,start_timestamp+duration_seconds as end_timestamp
FROM [table] ) as B
where B.start_timestamp>=A.start_timestamp
and B.start_timestamp<A.end_timestamp
and A.task_id<>b.task_id)
选择任务\u id
从[表]
其中任务id不在(
从中选择B.task\u id
(选择task_id、start_时间戳、duration_seconds、start_时间戳+duration_seconds作为end_时间戳。)
从[表])作为
交叉连接
(选择task_id、start_时间戳、duration_seconds、start_时间戳+duration_seconds作为end_时间戳。)
从[表]中选B
其中B.start\u timestamp>=A.start\u timestamp
B.start_timestamp=LAG_start_timestamp_1和start_timestamp=LAG_start_timestamp_2和start_timestamp=LAG_start_timestamp_3和start_timestamp刚刚写了一些非常相关的东西(在oracle中),也许它可以帮助某人。
我找到了我的解决方案
下面是一组帮助说明甘特图的代码
WITH
PERIODS AS
( SELECT TASK_ID LABEL ,
START_TIMESTAMP START_DATE ,
START_TIMESTAMP+DURATION_SECONDS END_DATE
FROM testet
),
LIMITS AS -- determine the earliest starting date and the latest end date to determine the overall width of the chart
( SELECT MIN(START_DATE) PERIOD_START ,
MAX(END_DATE) PERIOD_END ,
80 WIDTH -- set the width as the number of characters
FROM PERIODS
),
BARS AS
( SELECT LPAD(LABEL, '20')||'|' ACTIVITY ,
(START_DATE - PERIOD_START)/(PERIOD_END - PERIOD_START) * WIDTH FROM_POS, -- the starting position for the bar
(END_DATE - PERIOD_START)/(PERIOD_END - PERIOD_START) * WIDTH TO_POS -- the end position for the bar
FROM PERIODS , LIMITS
)
SELECT ACTIVITY||
LPAD('I',FROM_POS) ||
RPAD('-', TO_POS - FROM_POS, '-') ||
'I' GANTT
FROM BARS
UNION ALL
SELECT RPAD('_',WIDTH + 22,'_')
FROM LIMITS
UNION ALL
SELECT LPAD('|',21) ||
PERIOD_START ||
LPAD(PERIOD_END,
WIDTH - 11)
FROM LIMITS;
输出:
1|--I
2|I----I
3| I------I
4| I--I
5| I--I
6| II
7| I-I
8| I-----I
9| I-I
10| II
11| I--------I
12| I-----I
13| I---I
14| I--I
15| I--I
16| I------I
17| I-----I
18| I-I
19| II
20| I----I
21| I-----I
22| I--------I
23| I--I
24| I-------I
25| I---I
26| I-------I
27| I-------I
28| I-----I
29| I--------I
30| I--I
______________________________________________________________________________________________________
|1 194
您能否提供必须使用的SQL模式?您是否有开始日期时间和持续时间?或者您实际上是在使用数字开始索引和n位长字符串来指示任务持续时间?如果不存在,请选择…(时间范围重叠的任务)@PatrickM我有开始时间戳和持续时间。我刚刚将架构附加到问题的文本中。@DariusX。您是否考虑任务的顺序?例如,选择任务3