问题描述
我将子查询与分析结合使用,以识别和分组连续范围:
sql> WITH test_data AS (
2 SELECT 0 s, 2 dur FROM dual UNION ALL --# 鈻犫枲
3 SELECT 2 , 2 FROM dual UNION ALL --# 鈻犫枲
4 SELECT 10 , 1 FROM dual UNION ALL --# 鈻�
5 SELECT 13 , 4 FROM dual UNION ALL --# 鈻犫枲鈻犫枲
6 SELECT 15 , 4 FROM dual --# 鈻犫枲鈻犫枲
7 )
8 SELECT MIN(s) "begin", MAX(s + dur) "end"
9 FROM (SELECT s, dur, SUM(gap) over(ORDER BY s) my_group
10 FROM (SELECT s, dur,
11 CASE
12 WHEN lag(s + dur) over(ORDER BY s) >= s - 5 THEN
13 0
14 ELSE
15 1
16 END gap
17 FROM test_data
18 ORDER BY s))
19 GROUP BY my_group;
begin end
---------- ----------
0 4
10 19
解决方法
我有一个表,其中包含开始时间(在示例中使用数字以使其保持简单)以及事件的持续时间。
我想确定“块”及其开始时间和结束时间。
每当前一行的结束时间(开始时间+持续时间)(按开始时间排序)与当前行的开始时间之间的差值为时,>=5
应开始一个新的“块”。
这是我的测试数据,包括在注释中尝试进行图形解释的尝试:
WITH test_data AS (
SELECT 0 s,2 dur FROM dual UNION ALL --# 鈻犫枲
SELECT 2,2 FROM dual UNION ALL --# 鈻犫枲
SELECT 10,1 FROM dual UNION ALL --# 鈻�
SELECT 13,4 FROM dual UNION ALL --# 鈻犫枲鈻犫枲
SELECT 15,4 FROM dual --# 鈻犫枲鈻犫枲
)
--# Should return
--# 0 .. 4 --# 鈻犫枲鈻犫枲
--# 10 .. 19 --# 鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻�
第一个块开始于0
,结束于4
。由于与下一行的区别是>=5
,开始另一个块10
,终止于19
。
我可以使用来识别块的第一行LAG
,但是我还没有找到如何继续的方法。
我可以在PL / SQL循环中解决问题,但是出于性能原因,我试图避免这种情况。
关于如何编写此查询的任何建议?
预先感谢,彼得