Tags

, , , , , , , , ,

One of the frequently asked questions is about Gaps and Islands problems which involve finding a range of missing values (gaps) or a range of consecutive values (islands) in a sequence of numbers or dates.

Let’s see how to find the range of consecutive values in a sequence of numbers or dates.

NUMBERS:

SQL> WITH DATA(num) AS(
  2  SELECT  1 FROM dual UNION
  3  SELECT  2 FROM dual UNION
  4  SELECT  3 FROM dual UNION
  5  SELECT  5 FROM dual UNION
  6  SELECT  6 FROM dual UNION
  7  SELECT  7 FROM dual UNION
  8  SELECT 10 FROM dual UNION
  9  SELECT 11 FROM dual UNION
 10  SELECT 12 FROM dual UNION
 11  SELECT 13 FROM dual UNION
 12  SELECT 20 FROM dual
 13  )
 14  SELECT MIN(num),
 15         MAX(num)
 16  FROM
 17    ( SELECT num, num - row_number() OVER(ORDER BY num) rn
 18      FROM DATA
 19    )
 20  GROUP BY rn
 21  ORDER BY rn;

  MIN(NUM)   MAX(NUM)
---------- ----------
         1          3
         5          7
        10         13
        20         20

SQL>

DATES:

SQL> WITH DATA(dates) AS(
  2  SELECT  DATE '2015-01-01' FROM dual UNION
  3  SELECT  DATE '2015-01-02' FROM dual UNION
  4  SELECT  DATE '2015-01-03' FROM dual UNION
  5  SELECT  DATE '2015-01-05' FROM dual UNION
  6  SELECT  DATE '2015-01-06' FROM dual UNION
  7  SELECT  DATE '2015-01-07' FROM dual UNION
  8  SELECT  DATE '2015-01-10' FROM dual UNION
  9  SELECT  DATE '2015-01-11' FROM dual UNION
 10  SELECT  DATE '2015-01-12' FROM dual UNION
 11  SELECT  DATE '2015-01-13' FROM dual UNION
 12  SELECT  DATE '2015-01-20' FROM dual
 13  )
 14  SELECT MIN(dates),
 15         MAX(dates)
 16  FROM
 17    ( SELECT dates, dates - row_number() OVER(ORDER BY dates) rn
 18      FROM DATA
 19    )
 20  GROUP BY rn
 21  ORDER BY rn;

MIN(DATES MAX(DATES
--------- ---------
01-JAN-15 03-JAN-15
05-JAN-15 07-JAN-15
10-JAN-15 13-JAN-15
20-JAN-15 20-JAN-15

SQL>

Hope it helps!