0

Is there a way to create just using select statements a table that contains in a column the range of the repeating values like in this example?

Example:

from the input table:

id value:
1 25
2 25
3 24
4 25
5 25
6 25
7 28
8 28
9 11

should result:

range value
1-2 25
3-3 24
4-6 25
7-8 28
9-9 11

Note: The id values from the input table are always in order and the difference between 2 values ordered by id is always equal to 1

2
  • Welcome to Stack Overflow! Please specify the RDBMS that you are targeting by adding the appropriate tag (Oracle, SQL Server, MySQL, etc.). There may be answers that take advantage of language or product features that are not universally supported. Also, by tagging it with a specific RDBMS, your question may receive attention from people better suited to answer it. Commented Mar 31, 2013 at 19:52
  • any RDBMS is good as long the select does what it should. I will adapt the query later Commented Mar 31, 2013 at 20:00

3 Answers 3

2

You want to find sequences of consecutive values. Here is one approach, using window functions:

select min(id), max(id), value
from (select id, value,
             row_number() over (order by id) as rownum,
             row_number() over (partition by value order by id) as seqnum
      from t
     ) t
group by (rownum - seqnum), value;

This takes into account that a value might appear in different places among the rows. The idea is simple. rownum is a sequential number. seqnum is a sequential number that increments for a given value. The difference between these is constant for values that are in a row.

Let me add, if you actually want the expression as "1-2", we need more information. Assuming the id is a character string, one of the following would work, depending on the database:

select min(id)+'-'+max(id), . . .
select concat(min(id), '-', max(id)), . . .
select min(id)||'-'||max(id), . . .

If the id is an integer (as I suspect), then you need to replace the ids in the above expressions with cast(id as varchar(32)), except in Oracle, where you would use cast(id as varchar2(32)).

Sign up to request clarification or add additional context in comments.

2 Comments

thanks that seems to work perfectly! I just test it on my set of data
The second row_number() expression needs an ORDER BY in its OVER clause. Even if the dialect of SQL doesn't require one, the query needs it (...partition by value order by id)...) to be correct.
1
SELECT CONCAT(MIN(id), '-', MAX(id)) AS id_range, value
  FROM input_table
 GROUP BY value

Comments

0

Maybe this:

SELECT MIN(ID), MAX(ID), VALUE FROM TABLE GROUP BY VALUE

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.