一般联机事务处理系统的数据总是记录了一些具体详细的数据,比如考勤,X年X月X日 XX上班、下班等信息,但是在决策分析系统里,就需要对这些具体数据进行汇总分析,比如查询连续几天未考勤的人。如果把数据按要求进行多次整理、转储,或者采用游标等方式,这种查询连续数据的要求应该是可以满足的,但是有没有更简单的方法呢,今天看到一个,摘抄如下,免得忘记了,这个办法比较巧妙。 比如有一个表结构,

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

要查询kshm中连续的号段,语句如下:

SELECT b.fphm, MIN (b.kshm) Start_HM, MAX (b.kshm) End_HM  FROM 
	(SELECT a.*, TO_NUMBER (a.kshm - ROWNUM) cc FROM 
		(SELECT * FROM t  ORDER BY fphm, kshm) a
							) b  
GROUP BY b.fphm, b.cc

分析:第一个(最里层)查询只是排好序 第二个形成如下表

fphm kshm cc
2014 00000001 0
2014 00000002 0
2014 00000003 0
2014 00000004 0
2014 00000005 0
2014 00000007 1
2014 00000008 1
2014 00000009 1
2013 00000120 111
2013 00000121 111
2013 00000122 111
2013 00000124 111
2013 00000125 111

ROWNUM是递增1,号码如果是连续的也是递增1,这样如果号码是连续的,计算出的ks-rownum就是相同的,如果跳号,差值就变了。 第三步,分组,取得起、止号码。 总结,利用ROWNUM是递增1,号码如果是连续的也是递增1,等式两边同时加1差不变,如果号码不连续,跳变的地方就不是加1了,差就变了,这样就可以把连续的号码分在同一组里。同样的原理,查询连续几个月等问题只不过是数据类型不同,也可以这样做。