考虑行之间的“差异”对行进行分组

问题描述

我将子查询与分析结合使用,以识别和分组连续范围:

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循环中解决问题,但是出于性能原因,我试图避免这种情况。


关于如何编写此查询的任何建议?

预先感谢,彼得