SQL语句查询连续数据的方法
一般联机事务处理系统的数据总是记录了一些具体详细的数据,比如考勤,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了,差就变了,这样就可以把连续的号码分在同一组里。同样的原理,查询连续几个月等问题只不过是数据类型不同,也可以这样做。