select用存储过程返回的表
2007-11-11 05:51:30 来源:WEB开发网核心提示: 【select的使用技巧】 这个字句没什么,只是将几个select后产生的在结构完全一样的表加在地块,select用存储过程返回的表(8),变成一个表,具体的例子如下(以下例子不计较这种设计方法的好坏,不算入运行时间, use dele1 repl rec_orde with recn() all sele 0 us
【select的使用技巧】
这个字句没什么,只是将几个select后产生的在结构完全一样的表加在地块,变成一个表。具体的例子如下(以下例子不计较这种设计方法的好坏,只是说明命令的使用):
在做生产管理时,原材料的每笔进货、领用、报废、退货情况都要详细记录,老板随时都可能了解一个月内每种原材料的各种情况。而编程时对数据的规范化后,必然要用好几个表来记录这四种操作。现在为了更快的求出结果,命令当然是越少越好。各个表的结构如下:
进货单jhd:jhdbh,jhrq
进货单明细jhdmx:jhdbh,yclbh,jhsl
领货单lhd:lhdbh,lhrq
领货单明细lhdmx:lhdbh,yclbh,lhsl
报废单bfd:bfdbh,bfrq
报废单明细bfdmx:bfdbh,yclbh,bfsl
退货单thd:thdbh,thrq
退货单明细thdmx:thdbh,yclbh,thsl
原材料表yclb:yclbh,yclmc,yclgg
查询日期范围放在begindata,enddata里
为简便起见,只计算进货和退货,其它的照样做就行了。
Sele yclbh,sum(jhsl) as jhsl,100000.00-100000.00 as thsl ;
From jhd join jhdmx ;
On jhd.jhdbh=jhdmx.jhdbh ;
Where betw(jhd.jhrq,begindata,enddata) ;
Grou by yclbh ;
Union ;
Sele yclbh,100000.00-100000.00 ,sum(thsl) ;
From thd join thdmx ;
On thd.thdbh=thdmx.thdbh ;
Where betw(thd.thrq,begindata,enddata) ;
Grou by yclbh ;
Into curs temp1
这样就会产生这样的结果
yclbh jhsl thsl
00001 3432 0 ┐
00002 4234 0 │这些是第一节select产生的
…… ┘
00002 0 3423 ┐
00003 0 4234 │这些是第二节select产生的
…… ┘
现在再对临时表temp1进行一次合计
sele yclbh,sum(jhsl) as jhsl,sum(thsl) as thsl ;
from temp1 ;
grou by yclbh ;
into curs temp2
这个temp2就是结果了。
注1:如果要计算四种操作的话,就再加多两节select就行了。
注2:在命令里使用100000.00-100000.00这样奇怪的表达式是因为select对那些要计算的、事先不能确定长度和类型的字段,它是根据运算过程中产生的第一条记录中,该字段的值来确定这个字段的类型和长度。所以以上那条命令,第一个记录中thsl它是不知道长度是多少的,如果直接用0的话,那它就以为这个字段是数值型,长 ?,没有小数位。这当然不行,所以就要用这样一个表达式,来使它知道这个字段有9位长,小数位是2。
【group by与distinct的区别】
如果在字段串列中没使用字段函数,则group by参数与关键字distinct的效果相同。不过使用group by参数的效果显然要比使用关键字distinct来得快,而且在字段串列中的字段数越多,速度的差距会越大。
如果在字段串列中使用字段函数且使用group by 参数,则仍会显示出多个数据记录。但是如果于字段串列中使用字段且使用关键字distinct,则只有一个数据记录会显示出来。显然有字段时应使用group by 参数。
例子:
1、select name,max(salary) from test grou by name
2、select dist name,max(salary) from test
结果:
grouy by distinct
name salary name salary name salary
alex 20 alex 90 mary 95
alex 10 mary 44
alex 50 tom 95
alex 90
alex 30
tom 45
tom 55
tom 15
tom 95
mary 33
mary 44
【快速排名次】
考试排名次,一般有个要求,就是如果有两个人并列第一,那跟着的就不是第二名,而是第三名,即第二名跳空了。所以我想出以下这个方法。
面对大数据量的排名次,若用scan...endscan或do while这种方法,时间会非常长。1048576个记录中花了十多分钟才排了四十多万条记录。而我这种方法只需九十多秒(硬件:PII300(100*3),128M PC100,5.1G,VFP5.0),方法如下:
1。数据库dele:rec_id c(7) 升序;name c(10);fs n(4,1) 降序;rec_orde n(7),文件大小为29M,索引文件16M
2。建一个视图dele1
SELECT Dele.fs, Dele.rec_orde;
FROM dele;
ORDER BY Dele.fs DESC
3。根据视图dele1建立视图dele2
SELECT DISTINCT Dele1.fs, MIN(Dele1.rec_orde) AS rec_orde;
FROM dele1;
GROUP BY Dele1.fs
4。根据视图dele2和数据库dele建立视图dele3
SELECT Dele.rec_id, Dele.rec_orde, Dele2.rec_orde, Dele.fs;
FROM dele INNER JOIN dele2 Dele2 ;
ON Dele.fs = Dele2.fs;
ORDER BY Dele2.rec_orde
准备工作做好,现在可以排序了:
以上视图是事先做好的,不算入运行时间。
use dele1
repl rec_orde with recn() all
sele 0
use dele3
repl rec_orde_a with rec_orde_b all
brow
这就是你想要的!
以上是本人的一些心得体会,欢迎大家来信切磋。
hzzck@21cn.com
OICQ;2421316
这个字句没什么,只是将几个select后产生的在结构完全一样的表加在地块,变成一个表。具体的例子如下(以下例子不计较这种设计方法的好坏,只是说明命令的使用):
在做生产管理时,原材料的每笔进货、领用、报废、退货情况都要详细记录,老板随时都可能了解一个月内每种原材料的各种情况。而编程时对数据的规范化后,必然要用好几个表来记录这四种操作。现在为了更快的求出结果,命令当然是越少越好。各个表的结构如下:
进货单jhd:jhdbh,jhrq
进货单明细jhdmx:jhdbh,yclbh,jhsl
领货单lhd:lhdbh,lhrq
领货单明细lhdmx:lhdbh,yclbh,lhsl
报废单bfd:bfdbh,bfrq
报废单明细bfdmx:bfdbh,yclbh,bfsl
退货单thd:thdbh,thrq
退货单明细thdmx:thdbh,yclbh,thsl
原材料表yclb:yclbh,yclmc,yclgg
查询日期范围放在begindata,enddata里
为简便起见,只计算进货和退货,其它的照样做就行了。
Sele yclbh,sum(jhsl) as jhsl,100000.00-100000.00 as thsl ;
From jhd join jhdmx ;
On jhd.jhdbh=jhdmx.jhdbh ;
Where betw(jhd.jhrq,begindata,enddata) ;
Grou by yclbh ;
Union ;
Sele yclbh,100000.00-100000.00 ,sum(thsl) ;
From thd join thdmx ;
On thd.thdbh=thdmx.thdbh ;
Where betw(thd.thrq,begindata,enddata) ;
Grou by yclbh ;
Into curs temp1
这样就会产生这样的结果
yclbh jhsl thsl
00001 3432 0 ┐
00002 4234 0 │这些是第一节select产生的
…… ┘
00002 0 3423 ┐
00003 0 4234 │这些是第二节select产生的
…… ┘
现在再对临时表temp1进行一次合计
sele yclbh,sum(jhsl) as jhsl,sum(thsl) as thsl ;
from temp1 ;
grou by yclbh ;
into curs temp2
这个temp2就是结果了。
注1:如果要计算四种操作的话,就再加多两节select就行了。
注2:在命令里使用100000.00-100000.00这样奇怪的表达式是因为select对那些要计算的、事先不能确定长度和类型的字段,它是根据运算过程中产生的第一条记录中,该字段的值来确定这个字段的类型和长度。所以以上那条命令,第一个记录中thsl它是不知道长度是多少的,如果直接用0的话,那它就以为这个字段是数值型,长 ?,没有小数位。这当然不行,所以就要用这样一个表达式,来使它知道这个字段有9位长,小数位是2。
【group by与distinct的区别】
如果在字段串列中没使用字段函数,则group by参数与关键字distinct的效果相同。不过使用group by参数的效果显然要比使用关键字distinct来得快,而且在字段串列中的字段数越多,速度的差距会越大。
如果在字段串列中使用字段函数且使用group by 参数,则仍会显示出多个数据记录。但是如果于字段串列中使用字段且使用关键字distinct,则只有一个数据记录会显示出来。显然有字段时应使用group by 参数。
例子:
1、select name,max(salary) from test grou by name
2、select dist name,max(salary) from test
结果:
grouy by distinct
name salary name salary name salary
alex 20 alex 90 mary 95
alex 10 mary 44
alex 50 tom 95
alex 90
alex 30
tom 45
tom 55
tom 15
tom 95
mary 33
mary 44
【快速排名次】
考试排名次,一般有个要求,就是如果有两个人并列第一,那跟着的就不是第二名,而是第三名,即第二名跳空了。所以我想出以下这个方法。
面对大数据量的排名次,若用scan...endscan或do while这种方法,时间会非常长。1048576个记录中花了十多分钟才排了四十多万条记录。而我这种方法只需九十多秒(硬件:PII300(100*3),128M PC100,5.1G,VFP5.0),方法如下:
1。数据库dele:rec_id c(7) 升序;name c(10);fs n(4,1) 降序;rec_orde n(7),文件大小为29M,索引文件16M
2。建一个视图dele1
SELECT Dele.fs, Dele.rec_orde;
FROM dele;
ORDER BY Dele.fs DESC
3。根据视图dele1建立视图dele2
SELECT DISTINCT Dele1.fs, MIN(Dele1.rec_orde) AS rec_orde;
FROM dele1;
GROUP BY Dele1.fs
4。根据视图dele2和数据库dele建立视图dele3
SELECT Dele.rec_id, Dele.rec_orde, Dele2.rec_orde, Dele.fs;
FROM dele INNER JOIN dele2 Dele2 ;
ON Dele.fs = Dele2.fs;
ORDER BY Dele2.rec_orde
准备工作做好,现在可以排序了:
以上视图是事先做好的,不算入运行时间。
use dele1
repl rec_orde with recn() all
sele 0
use dele3
repl rec_orde_a with rec_orde_b all
brow
这就是你想要的!
以上是本人的一些心得体会,欢迎大家来信切磋。
hzzck@21cn.com
OICQ;2421316
更多精彩
赞助商链接