SQL查询连续号码段的巧妙解法

所属分类: 数据库 / 数据库其它 阅读数: 162
收藏 0 赞 0 分享

昨天在itpub看到这个帖子, 问题觉得有意思,, 就仔细想了想. 也给出了一种解决办法..:-)

问题求助,请高手指点..

我有一个表结构,
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

方法一: 引用自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

方法二: 使用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                                           

SQL> spool off

方法三: 今天早上wildflower给了我这个答案, 顿时觉得耳目一新啊..就贴出来与大家一起共享了^_^.


SQL> spool aaa.log
SQL> set echo on
SQL> select * from t;

no rows selected

SQL> select * from t;

      FPHM       KSHM
---------- ----------
      2014          1
      2014          2
      2014          3
      2014          4
      2014          5
      2014          7
      2014          8
      2014          9
      2013        120
      2013        121
      2013        122

      FPHM       KSHM
---------- ----------
      2013        124
      2013        125

13 rows selected.

SQL> @bbb.sql
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

SQL>

更多精彩内容其他人还在看

sql 左连接和右连接的使用技巧(left join and right join)

今天做项目,发现左右连接是不一样的。主要是说明了区别,是不是必须用左连接或右连接,大家可以根据需要选择。
收藏 0 赞 0 分享

mysql "group by"与"order by"的研究--分类中最新的内容

这两天让一个数据查询难了。主要是对group by 理解的不够深入。才出现这样的情况
收藏 0 赞 0 分享

MSSQL转MySQL数据库的实际操作记录

今天把一个MSSQL的数据库转成MySQL,在没有转换工具的情况下,对于字段不多的数据表我用了如下手功转换的方法,还算方便。MSSQL使用企业管理器操作,MySQL用phpmyadmin操作。
收藏 0 赞 0 分享

程序员应该知道的数据库设计的两个误区

在几乎所有的企业级应用程序中,包括各种MIS、ERP、CRM等等,都会使用数据库,这样的好处是显而易见的,很容易地实现了数据层和业务逻辑层的分离,而且对于性能的优化也在一定程度上提供了便利。
收藏 0 赞 0 分享

大数据量,海量数据处理方法总结

大数据量的问题是很多面试笔试中经常出现的问题,比如baidu google 腾讯这样的一些涉及到海量数据的公司经常会问到。
收藏 0 赞 0 分享

MDAC2.8 安装问题与解决方法

根据Windows XP的版本不同,有的版本需要安装MDAC2.8,一般Windows XP SP2或以上版本就不需要安装。不需要安装时系统会提示“MDAC 2.8 RTM 与此版本 Windows 不兼容。现在它的所有功能都成为 Windows 的一部分”。
收藏 0 赞 0 分享

SQLServer 2005 和Oracle 语法的一点差异小结

Microsoft SQL Server 和Oracle 语法的一点差异小结,需要的朋友可以参考下。
收藏 0 赞 0 分享

数据库设计规范化的五个要求 推荐收藏

通常情况下,可以从两个方面来判断数据库是否设计的比较规范。一是看看是否拥有大量的窄表,二是宽表的数量是否足够的少。
收藏 0 赞 0 分享

数据库为何要建立索引的原因说明

数据库索引是为了增加查询速度而对表字段附加的一种标识。见过很多人机械的理解索引的概念,认为增加索引只有好处没有坏处。
收藏 0 赞 0 分享

数据库测试 实用技巧及测试方法

软件应用程序已经离不开数据库。无论是在Web、桌面应用、客户端服务器、企业和个人业务,都需要数据库在后端操作。
收藏 0 赞 0 分享
查看更多