Pet*_*ang 6 sql oracle oracle11g
我有一个包含开始时间的表(在示例中使用数字来保持简单)和事件的持续时间.
我想确定"块"以及它们的开始和结束时间.
每当前一行的结束时间(开始时间+持续时间)(按开始时间排序)与当前行的开始时间之间的差异,就>=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 --# ?????????
Run Code Online (Sandbox Code Playgroud)
第一个块开始于0和结束4.由于与下一行的差异是>=5,开始另一个10结束于的块19.
我可以使用识别块的第一行LAG,但我还没有找到如何继续.
我可以在PL/SQL循环中解决问题,但出于性能原因,我试图避免这种情况.
有关如何编写此查询的任何建议?
彼得,先谢谢你
我使用子查询和分析来识别和分组连续范围:
\n\nSQL> WITH test_data AS (\n 2 SELECT 0 s, 2 dur FROM dual UNION ALL --# \xe2\x96\xa0\xe2\x96\xa0\n 3 SELECT 2 , 2 FROM dual UNION ALL --# \xe2\x96\xa0\xe2\x96\xa0\n 4 SELECT 10 , 1 FROM dual UNION ALL --# \xe2\x96\xa0\n 5 SELECT 13 , 4 FROM dual UNION ALL --# \xe2\x96\xa0\xe2\x96\xa0\xe2\x96\xa0\xe2\x96\xa0\n 6 SELECT 15 , 4 FROM dual --# \xe2\x96\xa0\xe2\x96\xa0\xe2\x96\xa0\xe2\x96\xa0\n 7 )\n 8 SELECT MIN(s) "begin", MAX(s + dur) "end"\n 9 FROM (SELECT s, dur, SUM(gap) over(ORDER BY s) my_group\n 10 FROM (SELECT s, dur,\n 11 CASE\n 12 WHEN lag(s + dur) over(ORDER BY s) >= s - 5 THEN\n 13 0\n 14 ELSE\n 15 1\n 16 END gap\n 17 FROM test_data\n 18 ORDER BY s))\n 19 GROUP BY my_group;\n\n begin end\n---------- ----------\n 0 4\n 10 19\nRun Code Online (Sandbox Code Playgroud)\n