Reputation: 479
So I have a bit of a coding challenge handed to me by my employer, and I was hoping that I may find some help in how to program this. I have a list of ID numbers that would be integers like this:
1
2
3
5
7
8
9
11
12
13
15
What I need to do is to take those numbers and create a list like this:
1-3
5
7-9
11-13
15
I have been researching this issue for the majority of the day. I did find this solution, which has helped me: Find missing int values
I took the code from there and I tweaked it to this:
SELECT CASE WHEN a.ids +1 = a.lead_no - 1 THEN TO_CHAR (a.ids)
ELSE TO_CHAR (a.lag_no) || '-' ||TO_CHAR (a.lead_no)
END as Missing_track_no
FROM (SELECT ids
,LEAD (ids, 1, NULL) OVER (ORDER BY ids ASC) as lead_no
,lag (ids, 1, null) over (order by ids asc) as lag_no
FROM xxxxx_test) a
WHERE a.lead_no = a.ids + 1
What I end up getting in my output is this:
-2
1-3
5-8
7-9
9-12
11-13
This is probably the closest I've come all day to a solution. I am hoping that there is someone who can take a look at my code and let me know where I am going wrong or if SQL isn't capable of producing a list like the one I've described above and I need to go another direction.
Thanks!!!
Upvotes: 2
Views: 102
Reputation: 1270713
You have the data in xxxxx_test
. That is a good start. You need to find sequences of adjacent numbers and then summarize them. My preferred solution is to use a difference between the number and row_number()
. This is constant for numbers that are increasing by 1:
select (case when min(ids) < max(ids) then min(ids) || '-' || max(ids)
else cast(min(ids) as varchar2(255))
end)
from (select t.*, ids - row_number() over (order by ids) as grp
from xxxxx_test t
) t
group by grp;
Upvotes: 1
Reputation: 479
This is the solution that I came up with that worked for me.
select case when b.min_id = b.max_id
then cast(b.min_id as varchar2(255))
else b.min_id || '-' || b.max_id
end as range
from (select min(a.ids) as min_id
,max(a.ids) as max_id
,a.grp
from (select t.ids
,ids - row_number() over (order by ids) as grp
from xxxxx_test t) a
group by a.grp
order by a.grp) b
Upvotes: 0