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!
Filed under: Gaps and Islands Tagged: dates, gaps, gaps and islands, islands, numbers, oracle, range, sequence, series, SQL
