需要在Oracle列表和个人中查找范围SQL
问题描述:
因此,我的雇主向我提出了一些编码挑战,并希望我可以在如何编程时找到一些帮助。 我有ID号的列表,会是这样的整数:需要在Oracle列表和个人中查找范围SQL
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不能生成像上面描述的那样的列表,并且我需要去另一个列表方向。
谢谢!
答
您有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;
答
这是我想出来的解决方案,为我工作。
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
嗨戈登,非常感谢您的帮助!您的解决方案对我无效,这可能是因为我在遗留系统上。我试图运行代码时遇到了很多错误。但是,由于部分代码,我能够找到解决方案,我非常感谢。我已在下面发布我的解决方案。再次感谢!!! – Perdue 2015-02-25 15:10:02
你能不能让我知道如何作为GRP的ids - row_number()结束(按ID排序)?我只想了解它背后的机制。谢谢! – Perdue 2015-02-25 15:17:07
@Perdue。 。 。我认为语法错误只是在'select'外面的'ids'上写的。 – 2015-02-26 00:58:44