澳门金沙vip 6

澳门金沙vipSQL查询连续号码段的巧妙解法

在ITPUB上有一则非常巧妙的SQL技巧,学习一下,记录在这里。
最初的问题是这样的: 我有一个表结构, 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 ITPUB上的朋友给出了一个非常巧妙的答案:
SELECTb.fphm,MIN(b.kshm)Start_HM,MAX(b.kshm)End_HM
FROM(SELECTa.*,TO_NUMBER(a.kshm-ROWNUM)cc FROM(SELECT* FROMt
ORDERBYfphm,kshm)a )b GROUPBYb.fphm,b.cc

VFP
SQL-select查询连续号段范围及断号问题

原出处:

 问题:有一列数字{7,88,9,8,103,12,11,102,101},有两个问题:
(1)找出连续段并记录连续段的起、始值;
(2)找出数列中间的中断部分。
对于前一个问题,网上流行的有好多例子,针对mysql、sql等等的都有,就是没找到针对VFP,仔细学习了一下,发现原理只有一个: 依有序数列与项号的关系进行分组查询。
实现的方法步骤:
(1)按由小到大的顺序进行排序;
(2)与对应项号做差;
(3)根据差值进行分组;
(4)取得每组的最小值与最大值。
而对于后一个问题网上的介绍很少,在此文中准备使用VFP
SQL-select来分析解决这两个问题。
首先,建立数据表并准备测试数据
CREATE TABLE test (数字 N(5,0))
INSERT INTO test values(7)
INSERT INTO test values(88)
INSERT INTO test values(9)
INSERT INTO test values(8)
INSERT INTO test values(103)
INSERT INTO test values(12)
INSERT INTO test values(11)
INSERT INTO test values(102)
INSERT INTO test values(101)
数据准备好了,先来解决第一个问题。
第一步:排序
 SELECT 数字 FROM test ORDER BY 数字
澳门金沙vip 1
第二步: 生成项号(即行号或者记录号)
SELECT a.数字,RECNO() as 项号 FROM (;
SELECT 数字 FROM test ORDER BY 数字) a 
澳门金沙vip 2
第三步:数字与项号做差 
SELECT b.数字,b.项号,b.数字-b.项号 as 分组 FROM (;
SELECT a.数字,RECNO() as 项号 FROM (;
SELECT 数字 FROM test ORDER BY 数字) a) b 
澳门金沙vip 3
第四步:生成结果 
SELECT c.分组,MIN(c.数字) as 起,MAX(c.数字) as 止 FROM (;
SELECT b.数字,b.项号,b.数字-b.项号 as 分组 FROM (;
SELECT a.数字,RECNO() as 项号 FROM (;
SELECT 数字 FROM test ORDER BY 数字) a) b) c GROUP BY c.分组 
澳门金沙vip 4
至此,第一个问题算是解决了,那么我们来分析第二个问题。 观察第一个问题的最后结果,不难发现第二个问题的答案
10,10
13,87 
89,100
澳门金沙vip, 也能发现其实就是:每一行“止”+1为起始,下一行“起”-1为终了,为此,执行了下边的命令
SELECT c.分组,Max(c.数字)+1 as 起,Min(c.数字)-1 as 止 FROM (;
SELECT b.数字,b.项号,b.数字-b.项号 as 分组 FROM (;
SELECT a.数字,RECNO() as 项号 FROM (;
SELECT 数字 FROM test ORDER BY 数字) a) b) c GROUP BY c.分组
得出
澳门金沙vip 5
看着这个结果,觉得把“止”列往前移上一行和“起”列错位对应起来,再把有空值的行去掉就应该是结果了,试试下边命令:
SELECT DISTINCT e.起,f.止 FROM (;
SELECT c.分组,Max(c.数字)+1 as 起,Min(c.数字)-1 as 止 FROM (;
SELECT b.数字,b.项号,b.数字-b.项号 as 分组 FROM (;
SELECT a.数字,RECNO() as 项号 FROM (;
SELECT 数字 FROM test ORDER BY 数字) a) b) c GROUP BY c.分组) d,(;
SELECT 起,RECNO() as 行号 FROM d) e,(;
SELECT 止,RECNO() as 行号 FROM d) f WHERE e.行号+1=f.行号
得出

澳门金沙vip 6
到此也就解决了第二个问题。
由于个人水平所限,命令可能写的不明了简单,但总算是能达到目的,顺便感慨一下select命令的强大 。

 

最后也附上网友们在Sql及Mysql里的解决第一个问题的办法。
<转载一:sql实现>
学习-SQL查询连续号码段的巧妙解法

作者:eygle | English
【转载时请标明出处和作者信息】【恩墨学院
OCM培训传DBA成功之道】

在ITPUB上有一则非常巧妙的SQL技巧,学习一下,记录在这里。