So, I have a large set of numbers, basically 1001 .. 150000 for a database using MySQL
There are a ton of gaps in the IDs on the database, so not all IDs exist. It can go from 100000 – 10500, then the next number will be 10675, and so fourth.
I want to make the IDs shortened, such as 1001..3000, x, x, x, 55000..101000 etc
I’m sure it’s simple. Thanks in advanced!!
SELECT id FROM table_name WHERE data = x
give me above info.
I used
select group_concat(id) from items where id>1000
to get all ids in a comma separated list. How do I shrink this to be more clean? Basically to add ".." to a series of sequential numbers
I am using perl – just not sure of the syntax to make it work
3
Answers
To shorten the sequence of IDs into ranges like
1001..3000
,55000..101000
, etc., you can use a combination of SQL and Perl. MySQL itself doesn’t have built-in functionality to directly compress ranges with ".." notation, but you can achieve this with a bit of SQL and some post-processing in Perl.Here’s a step-by-step approach to accomplish this:
1. Extract Sequential IDs in SQL
First, get the IDs from the database:
2. Process IDs in Perl
Use Perl to process the list of IDs and convert them into ranges. Here’s a basic Perl script to accomplish this:
Explanation of the Perl Script
3. Integration
This approach separates the concerns of querying the database and processing the data, making it easier to manage and adapt to different scenarios.
This is a variation on the "gaps and islands" problem.
First, match up each ID with its previous ID.
If we have 1, 2, 3, 5, 7, 8, 9, 10, 12 this produces…
Now we can find the start of each group by finding the rows where id – prev_id <> 1, or if prev_id is null. That’s 1, 5, 7, and 12 above. The end is the prev_id of the next matching row. If there is no next row, the end is the highest ID.
We can then format this using a case statement to identify groups of one ID.
You can then
group concat
the case to get1..3,5,7..10,12
.Demonstration.
here is a short query for you
result
sample
dbfiddle