转:Oracle中如何把分段范围解析出来.值得借鉴
2010-04-21 17:01 Tracy. 阅读(643) 评论(0) 编辑 收藏 举报
如何把分段范围解析出来
比如:
编号
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
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
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;
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;
本文来自博客园,作者:Tracy.,转载请注明原文链接:https://www.cnblogs.com/tracy/archive/2010/04/21/1717387.html