Reputation: 127
Id value
1 5
1 6
1 8
1 9
1 10
Result should be like below
Id minValue maxValue
1 5 6
1 8 10
Previous value difference should be 1 otherwise need to insert other row
Upvotes: 0
Views: 74
Reputation: 13509
This is famous GAPS and ISLANDS problem. You can read this wonderful article from Lalit Kumar B for detailed description. You can try below query -
SELECT id, MIN(value), MAX(value)
FROM (SELECT id, value, value - ROW_NUMBER() OVER(PARTITION BY id ORDER BY value) rn
FROM test) T
GROUP BY id, rn;
Here is the Fiddle
Upvotes: 3
Reputation: 191235
If you subtract the position of each value within the list of values for that ID (which you can get with an analytic function) from the value itself:
value - dense_rank() over (partition by id order by value)
then consecutive (or duplicate) values will get the same result:
select id, value,
value - dense_rank() over (partition by id order by value)
from your_table;
ID VALUE GRP
---------- ---------- ----------
1 5 4
1 6 4
1 8 5
1 9 5
1 10 5
You can then aggregate using those differences:
select id, min(value) as minvalue, max(value) as maxvalue
from (
select id, value,
value - dense_rank() over (partition by id order by value) as grp
from your_table
)
group by id, grp
order by id, minvalue;
ID MINVALUE MAXVALUE
---------- ---------- ----------
1 5 6
1 8 10
You could use row_number()
instead of dense_rank()
if there are no duplicates.
Upvotes: 3