I am looking for ideas on how to group numbers into low and high ranges in Oracle SQL. I looking to to avoid cursors...any ideas welcome
Example input
ID | LOW | HIGH |
---|---|---|
A | 0 | 2 |
A | 2 | 3 |
A | 3 | 5 |
A | 9 | 11 |
A | 11 | 13 |
A | 13 | 15 |
B | 0 | 1 |
B | 1 | 4 |
B | 7 | 9 |
B | 11 | 12 |
B | 12 | 17 |
B | 17 | 18 |
Which would result in the following grouping into ranges
ID | LOW | HIGH |
---|---|---|
A | 0 | 5 |
A | 9 | 15 |
B | 0 | 4 |
B | 7 | 9 |
B | 11 | 18 |
This is a Gaps & Islands problem. You can use the traditional solution.
For example:
select max(id) as id, min(low) as low, max(high) as high
from (
select x.*, sum(i) over(order by id, low) as g
from (
select t.*,
case when low = lag(high) over(partition by id order by low)
and id = lag(id) over(partition by id order by low)
then 0 else 1 end as i
from t
) x
) y
group by g
Result:
ID LOW HIGH
--- ---- ----
A 0 5
A 9 15
B 0 4
B 7 9
B 11 18
See running example at db<>fiddle.