转:Oracle中如何把分段范围解析出来.值得借鉴

如何把分段范围解析出来

比如:
    编号
     1
     2
     3
     5
     6
     8

可以把它变成 1-3,5-6,8-8

方法是,通过rownum做辅助,通过 序号-rownum,如果连续,这个差值就是一样的;
    编号   rownum   编号-rownum   
     1     1               0
     2     2               0
     3     3               0
     5     4               1
     6     5               1
     8     6               2

然后对(编号-rownum )进行guoup by 分组 ;获取编号的最小最大值就能生成范围;


以上这个技巧,很多网上都介绍过,

今天白天,我一个以前的同事也问了这个问题,不过他问的是“反”的:

就是给一个编号范围;

比如:
      开始编号  结束编号
          1            3
          5            6
          8            8

现在要把它变成:

    编号
     1
     2
     3
     5
     6
     8

这个问题,我一开始以为很简单的,用connect by level之类的技巧就能搞定;

有兴趣的,大家研究下。
 
  解决方案1:
WITH tmp AS (SELECT   1 a, 3 b FROM DUAL
             UNION ALL
             SELECT   5, 6 FROM DUAL
             UNION ALL
             SELECT   8, 8 FROM DUAL
             UNION ALL
             SELECT   10 start_no, 14 end_no FROM DUAL)
    SELECT   a + ROW_NUMBER () OVER (PARTITION BY a ORDER BY ROWNUM) - 1 newodr,
             a,
             b
      FROM   (SELECT   a,
                       b,
                       SUM (b - a + 1) OVER (ORDER BY ROWNUM) - ROWNUM + 1 c
                FROM   tmp) a
CONNECT BY   ROWNUM <= c
 
   解决方案2:
WITH t AS (SELECT   1 start_no, 3 end_no FROM DUAL
           UNION ALL
           SELECT   5 start_no, 6 end_no FROM DUAL
           UNION ALL
           SELECT   8 start_no, 8 end_no FROM DUAL
           UNION ALL
           SELECT   10 start_no, 14 end_no FROM DUAL)
  SELECT   start_no + rn - 1
    FROM   t,
           (    SELECT   ROWNUM rn
                  FROM   DUAL
            CONNECT BY   ROWNUM <=
                            (    SELECT   MAX (end_no - start_no + 1) FROM t))
   WHERE   end_no - start_no + 1 >= rn
ORDER BY   1;
魔兽就是毒瘤,大家千万不要玩。
原文地址:https://www.cnblogs.com/tracy/p/1717387.html