我有一个表,其中包含开始时间(在示例中使用数字以保持简单)和事件的持续时间。
我想确定“块”及其开始时间和结束时间。
每当前一行(按开始时间排序)的结束时间(开始时间 + 持续时间)与当前行的开始时间之间的差值为>=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 循环中解决该问题,但出于性能原因我试图避免这种情况。
关于如何编写此查询有什么建议吗?
预先感谢,彼得
我使用子查询和分析来识别和分组连续范围:
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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)