所以我的雇主给了我一点编程挑战,我希望我能在如何编程方面找到一些帮助。我有一个ID号码列表,它是如下所示的整数:
1
2
3
5
7
8
9
11
12
13
15
我需要做的是获取这些数字,并创建一个如下列表:
1-3
5
7-9
11-13
15
我一天中的大部分时间都在研究这个问题。我确实找到了这个解决方案,它对我很有帮助:Find missing int values
我从那里获取了代码,并将其调整为:
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
我最终在我的输出中得到的是:
-2
1-3
5-8
7-9
9-12
11-13
这可能是我一天中最接近解决方案的一次。我希望有人能看一看我的代码,告诉我哪里出了问题,或者SQL不能生成像我上面描述的那样的列表,我需要转向另一个方向。
谢谢!
发布于 2015-02-25 05:35:59
您已经在xxxxx_test
中获得了数据。这是一个很好的开始。您需要找到相邻数字的序列,然后对它们进行汇总。我首选的解决方案是使用数字和row_number()
之间的差值。对于递增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;
发布于 2015-02-25 23:17:33
这是我想出的解决方案,它对我有效。
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
https://stackoverflow.com/questions/28706711
复制相似问题