转自lastwinner
此文应与http://blog.itpub.net/post/7102/44843对比阅读
相关文章:http://lastwinner.itpub.net/post/7102/248528
问题求助,请高手指点..
我有一个表结构,
fphm,kshm
2014,00000001
2014,00000002
2014,00000003
2014,00000004
2014,00000005
2014,00000007
2014,00000008
2014,00000009
2013,00000120
2013,00000121
2013,00000122
2013,00000124
2013,00000125
(第二个字段内可能是连续的数据,可能存在断点。)
怎样能查询出来这样的结果,查询出连续的记录来。
就像下面的这样?
2014,00000001,00000005
2014,00000009,00000007
2013,00000120,00000122
2013,00000124,00000125
http://www.itpub.net/354052.html
【By hmxxyy】
抛一块砖
SQL> select * from gap;
ID SEQ
---------- ----------
1 1
1 4
1 5
1 8
2 1
2 2
2 9
select res1.id, res2.seq str, res1.seq end
from
(select rownum rn, c.* from (select * from gap a where not exists (select null from gap b where b.id = a.id and a.seq = b.seq - 1) order by id, seq) c ) res1,
(select rownum rn, d.* from (select * from gap a where not exists (select null from gap b where b.id = a.id and a.seq = b.seq + 1) order by id, seq) d ) res2
where res1.id = res2.id
and res1.rn = res2.rn
/
ID STR END
--------- ---------- ----------
1 1 1
1 4 5
1 8 8
2 1 2
2 9 9
http://blog.itpub.net/post/4791/27805
A much better solution:
SQL> select b.fphm,min(b.kshm),max(b.kshm)
2 from (
3 select a.*,to_number(a.kshm-rownum) cc
4 from (
5 select * from t order by fphm,kshm
6 ) a
7 ) b
8 group by b.fphm,b.cc
9 /
【By jametone】http://blog.itpub.net/post/5042/27936
使用lag/lead分析函数进行处理.. 楼上的方法确实挺好用就是觉得表扫描/表连接比较多, 可能数据量大了. 速度会比较慢, 当然我的这种方法由于使用分析函数使用的比较频繁.所以排序量可能比上一种要多..
SQL> select fphm,lpad(kshm,8,'0') kshm
2 from t
3 /
FPHM KSHM
---------- ----------------
2014 00000001
2014 00000002
2014 00000003
2014 00000004
2014 00000005
2014 00000007
2014 00000008
2014 00000009
2013 00000120
2013 00000121
2013 00000122
FPHM KSHM
---------- ----------------
2013 00000124
2013 00000125
13 rows selected.
SQL> set echo on
SQL> @bbb.sql
SQL> select fphm,lpad(kshm,8,'0') start_kshm,lpad(prev_prev_kshm,8,'0') end_kshm
2 from (
3 select fphm,kshm,next_kshm,prev_kshm,
4 lag(kshm,1,null) over (partition by fphm order by kshm )next_next_kshm,
5 lead(kshm,1,null) over (partition by fphm order by kshm ) prev_prev_kshm
6 from (
7 select *
8 from (
9 select fphm,kshm,
10 lead(kshm,1,null) over (partition by fphm order by kshm) next_kshm,
11 lag(kshm,1,null) over (partition by fphm order by kshm) prev_kshm
12 from t
13 )
14 where ( next_kshm - kshm <> 1 or kshm - prev_kshm <> 1 )
15 or ( next_kshm is null or prev_kshm is null )
16 )
17 )
18 where next_kshm - kshm = 1
19 /
FPHM START_KSHM END_KSHM
---------- ---------------- ----------------
2013 00000120 00000122
2013 00000124 00000125
2014 00000001 00000005
2014 00000007 00000009
【By wlidflower】
SQL> select b.fphm,min(b.kshm),max(b.kshm)
2 from (
3 select a.*,to_number(a.kshm-rownum) cc
4 from (
5 select * from t order by fphm,kshm
6 ) a
7 ) b
8 group by b.fphm,b.cc
9 /
FPHM MIN(B.KSHM) MAX(B.KSHM)
---------- ----------- -----------
2013 120 122
2013 124 125
2014 1 5
2014 7 9
1 select max(fphm),min(kshm),max(kshm)
2 from test
3* group by fphm||kshm-rownum
SQL> /
MAX(FPHM) MIN(KSHM) MAX(KSHM)
---------- ---------- ----------
2013 124 125
2014 7 9
2014 1 5
2013 120 122
【By lastwinner】
select fphm, nvl(lag(e)over(partition by fphm order by s),minn) ST,nvl(S,maxn) EN from (select fphm, lag(kshm,1)over(partition by fphm order by kshm) S, kshm E, min(kshm)over(partition by fphm) minn, max(kshm)over(partition by fphm) maxn from t) where nvl(E-S-1,1)<>0;
FPHM ST EN
---------- ---------- ----------
2013 00000120 00000122
2013 00000124 00000125
2014 00000001 00000005
2014 00000007 00000009
思路参考:http://blog.itpub.net/post/7102/44843
其实WlidFlower的方法还可用row_number来减少嵌套层数,那可谓是最佳方法了。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26844646/viewspace-751619/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/26844646/viewspace-751619/