需要在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; 
+0

嗨戈登,非常感谢您的帮助!您的解决方案对我无效,这可能是因为我在遗留系统上。我试图运行代码时遇到了很多错误。但是,由于部分代码,我能够找到解决方案,我非常感谢。我已在下面发布我的解决方案。再次感谢!!! – Perdue 2015-02-25 15:10:02

+0

你能不能让我知道如何作为GRP的ids - row_number()结束(按ID排序)?我只想了解它背后的机制。谢谢! – Perdue 2015-02-25 15:17:07

+0

@Perdue。 。 。我认为语法错误只是在'select'外面的'ids'上写的。 – 2015-02-26 00:58:44

这是我想出来的解决方案,为我工作。

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