VFP第9部分(查询统计及扫描循环)解析课件.ppt
数据表的查询(P67页),表中记录的查询就是在表的所有记录中查找满足条件的记录,并把记录指针定位在要查询的记录上。这里介绍2种传统查询方法:顺序查询和索引查询。 1)顺序查询(条件定位) 顺序查询是一种按照记录的排列顺序,在表文件中逐个地查找满足条件的记录,查询速度较慢。 (1)LOCATE命令 格式:LOCATE 范围 FOR|WHILE 功能:按顺序搜索数据表,并将记录指针定位在满足条件的第一条记录上。,(2)CONTINUE命令 格式:CONTINUE 功能:LOCATE命令执行后继续移动记录指针到下一条满足条件的记录。,说明:LOCATE命令在指定范围内查找满足条件的第一条记录,并将该记录置为当前记录。如果找不到符合条件的记录,则显示“已到定位范围末尾”;缺省范围子句为ALL。CONTINUE命令只能放在LOCATE命令后使用;可多次执行CONTINUE命令。若LOCATE发现一条满足条件的记录,可使用 RECNO()返回该记录号,且FOUND()函数的返回值为“真”(.T.),EOF( )函数的返回值为“假”(.F.)。,locate 范围 for ,命令格式:,继续查找命令,命令格式:,continue,不能单独使用,【例】 在学生档案表(dab.dbf)中找出计算机1班的前2位同学,并将记录输出。USE dabLOCATE ALL FOR 专业班级=计算机1班? FOUND() & 结果为.T.DISPLAYCONTINUE & 查找满足条件的下一记录? FOUND()DISPLAYUSE,2)索引查询(p79页) 索引查询是在数据表文件建立了索引的基础上进行的,因此必须打开相应的索引文件。打开索引后,记录将按索引关键字值升序或降序排列,查询的速度比顺序查询要快得多。 (1)FIND命令 格式:FIND| 功能:在索引文件中查找索引关键字值与指定的字符串或数值常数相等的记录。,找什么索引什么,说明:FIND只能找C、N型数据,字符串常量可不加定界符;字符串变量前面必须用宏代换函数&。FIND找到了与索引关键字相匹配的记录,则 RECNO()返回匹配记录的记录号;FOUND()返回“真”(.T.);EOF()返回“假”(.F.)。FIND命令找到的是与查询数据相匹配的第一条记录,没有继续查询命令。,(2)SEEK命令格式:SEEK 功能:在索引文件中查找索引关键字值与指定表达式值相等的记录。 说明:只能在索引文件打开后使用 SEEK命令。SEEK命令查找的是表达式,表达式可以是C、N、D、L型的常量、变量及其组合。查找的字符串常量必须用定界符;变量不用&函数。如果 SEEK找到了与索引关键字相匹配的记录,则 RECNO()返回匹配记录的记录号;FOUND()返回“真”(.T.);EOF()返回“假”(.F.)。若找不到相匹配的关键字,则 RECNO()返回表中记录个数加 1。FOUND()返回“假”(.F.);EOF()返回“真”(.T.)。,find |&seek |,可以不加引号,只能是字符、数值和日期表达式,【例】使用FIND命令和SEEK命令在学生档案表(dab.dbf)中按如下要求分别查找满足条件的第一条记录。查找姓名为“那措央中”的记录。查找1987年出生的男生记录。USE dab INDEX ON 姓名 TAG xmsyFIND 那措央中 &或 SEEK 那措央中 DISPLAYINDEX ON 性别+RIGH(DTOC(出生日期),2) TAG xbrq SEEK 男+ 87 & 按表达式的值查找?FOUND() & 根据FOUND()的值判断查找结果,【例】:逐条显示学生表中84年出生的学生的信息。,clearuse 学生do while .not.eof()if year(出生日期)=1984 dispendifskip enddousecancel,循环体,方法一:,clearuse 学生Locate for year(出生日期)=1984 do while .not.eof()dispcontinue enddousecancel,方法二:,扫描循环(scanendscan循环) 格式: (见教科书146页,练习册148页),该循环只对数据表中的指定记录逐个进行某种处理,方法三:,clearuse 学生scan for year(出生日期)=1984 dispendscanusecancel,当循环 go top do whil not eof() 处理一个记录 skip endd,扫描循环scan 处理一个记录ends,例:在student.dbf中输入学生姓名,查询该学生的信息。(实验14 任务1(1) ),方法一: clear use student accept 请输入学生姓名: to xm locate for 姓名=xm if found() display else ?查无此人 endif use return,方法二:clearuse studentindex on 姓名 tag sxmaccept 请输入学生姓名: to xmseek xmif found()dispelse ?查无此人endifusereturn,例:在student.dbf中统计江苏籍学生的人数。 (实验14 任务1(1) ),方法一: clear use student store 0 to rs,zf do while not eof() if 籍贯=江苏 rs=rs+1 endif skip enddo ? rs use return,方法二: clear use student rs=0 locate for籍贯=江苏 do while found() rs=rs+1 continue enddo ?rs use return,方法三: clear use student rs=0 scan for籍贯=江苏 rs=rs+1 endscan ?rs use return,例: 对学生表逐条统计560分以上的学生人数,并显示。,数据表的统计运算(P79-81),1)统计记录个数命令格式:COUNT 范围FOR|WHILE TO 功能:统计当前数据表中指定范围内满足条件的记录个数。统计主要是对于数据表中的记录数、数字型字段进行纵向统计。 说明:如果省略范围和FOR|WHILE ,则对当前表中所有记录进行统计。TO 选项是将统计结果存于内存变量中。,【例】统计学生档案表(dab.dbf)中“英语3班”的学生人数,统计结果保存到内存变量M中。命令序列如下:USE dabCOUNT FOR 专业班级=“英语3班” TO M & 在状态行显示“4 记录”?英语3班的学生人数有+ALLTRIM(STR(M)+人 &将统计结果显示在主窗口上,2)数值字段求和命令格式:SUM 范围FOR|WHILE TO 功能:对当前表的指定数值型字段或全部数值型字段在列方向上求和。说明:指定要求和的一个或多个字段或者字段表达式。如果省略,则对所有数值型字段求和。缺省范围和FOR|WHILE ,则对所有记录求和。若指定,则将求和结果依次存于相对应的内存变量中,但要注意,其内存变量的个数必须与表达式列表或数值字段的个数相等,否则将出错。,【例】对zggz.dbf表完成下列操作。对所有数值字段求和。USE zggzSUMUSE统计计算结果如下所示:,对销售科的基本工资、岗位工资字段求和,结果保存到指定的内存变量中,并显示求和结果。USE zggzSUM 基本工资, 岗位工资 TO X,Y FOR 部门=销售科 ALL?X,YUSE显示结果如下:1 430.00 1 230.00,3)数值字段求平均值命令格式:AVERAGE 范围FOR|WHILE TO 功能:对当前表中的数值字段在列方向上求平均值。各选项的含义与SUM命令相同。,【例】对zggz.dbf表中销售科的jbgz、gwgz字段求平均值,结果保存到指定的内存变量中,并显示计算结果。USE zggzAVERAGE 基本工资,岗位工资 TO M,N FOR 部门=销售科 ALL?M,N计算结果如下:715.00 615.00,4)多功能计算命令格式: CALCULATE 范围FOR|WHILE TO 功能:对表中的字段或包含字段的表达式作统计计算。可以是下列函数的任意组合,这些函数仅用于 CALCULATE命令。说明:这里的指具有统计意义的函数。这些函数是: CNT(): 统计记录数。 SUM(): 对当前表数值字段求和。 AVG(): 对当前表数值字段求平均值。 MAX(): 对当前表的C、N、D字段求最大值。 MIN(): 对当前表的C、N、D字段求最小值。,CNT()、SUM()、AVG() 、MAX() 、 MIN(),SUM()、AVG()这样的函数形式只能放在该命令后使用。MAX()、MIN()这样的函数形式放在该命令后是指对当前表字段列方向求最大/小值。,【例】 计算zggz.dbf表中实发工资字段的最大值、最小值、平均值、总和。USE zggzCALCULATE MAX(实发工资),MIN(实发工资),AVG(实发工资),SUM(实发工资)计算结果为:,5)分类汇总命令格式:TOTAL TO ON 范围 FIELDS FOR|WHILE 功能:对数值型字段按指定的关键字段进行分类求和,结果存入指定的汇总表文件中。说明:执行该命令要生成一个新的表文件。使用该命令前,用于汇总的数据表必须按进行排序或索引FIELDS 指定汇总字段,汇总字段必须是数值型字段,若该项缺省则对所有数值型字段求和。范围缺省时是对表中所有记录进行操作。,汇总表文件中的一个记录值是按下述原则确定的: 将当前表中“关键字段”值相同的记录汇总成一条记录;在该记录中,属于“字段名表”指定的数值型字段的值由各条同类记录对应字段之值求和产生;其余字段的值取同类记录中第一条记录对应字段的值。,【例】对zggz.dbf表进行下列汇总统计。按部门对所有字段进行汇总统计,汇总表文件名为gzhz1.dbf,命令序列如下:USE zggzINDEX ON 部门 TO bmsy1TOTAL TO gzhz1 ON 部门 ALLUSE gzhz1 &打开汇总表文件BROWSE,汇总表中的记录如下图所示。,可以看出,在gzhz1.dbf表中仅有4条记录,因为原表中只有4个部门。,对zggz表中部门是厂部和销售科的记录按基本工资、岗位工资和实发工资字段进行汇总统计,汇总表文件名为gzhz2.dbf,命令序列如下 USE zggz INDEX ON 部门 TO bmsy2 TOTAL TO gzhz2 ON 部门 FOR 部门=“厂部” OR 部门=“销售科”; FIELDS 基本工资,岗位工资,实发工资 ALL USE gzhz2 &打开汇总表文件 BROWSE 汇总表中的记录如下图所示。,例:有如下数据表jf.dbf,按性别汇总积分。,use jfindex on 性别 tag xbtotal on 性别 to hz fields 积分use hzbrowse,例:现有学生成绩表XSCJ.DBF,表结构及部分记录如下:XSCJ.DBF表结构:学号(C/10),课程号(C/6),成绩(N/7/1);XSCJ.DBF的部分记录: 学号 课程号 成绩 S01 CA01 88 S01 CA02 65 S02 CA01 72 S02 CA02 51 S01 CA03 34 设该程序的文件名为cx4_1.PRG.应用分类求和(TOTAL)与统计(COUNT)命令,根据用户输入的学号,计算对应学号的学生的平均成绩。屏幕显示格式如下: 学生的学号 平均成绩 最高成绩 最低成绩 XXXXXXXXXX XXXXX XXXXX XXXXX,(实验14 任务2(1) ),use xscjAccept “输入学生学号:” to xhCalculate cnt(),max(成绩),min(成绩) to ks,zd,zx for学号=xhindex on 学号 tag xhtotal on 学号 to hz fields 成绩use hzLocate for 学号=xh?”学生的学号 平均成绩 最高成绩 最低成绩”?学号,成绩/ks,zd,zxreturn,例:已知某单位教师工资表JS.dbf有如下记录:Record# 编号 姓名 年龄 工资 1 3001 李丽珍 36 690 2 3002 刘苏 51 1680 3 3003 末言 22 820 4 3004 魏虎豹 46 960 5 3005 罗山 40 1100 6 3006 甘甜 30 920 7 3007 丰潇潇 47 1200下列程序用于统计工资表JS.DBF中40岁以上(包括40岁)的教师的平均工资。请填空完成。,USE JSS=0N=0LOCATE FOR DO WHILE S=S+工资N=N+1 ENDDO ?S/N USE,年龄=40not eof()continue,例:设有数据库STUDENT.DBF的结构的内容如下: 记录号 姓名(C) 性别(C) 出生日期(D) 总分(N) 1 王青川 男 06/08/80 586.00 2 李凤 女 08/09/82 532.00 3 张方 男 05/06/81 618.00 4 赵雯 女 07/08/82 609.00 5 孙笑 女 06/23/80 589.00,阅读下列程序,写出运行结果:CLEARUSE STUDENTSCAN IF 性别=女 SKIP ELSE ? 总分 ENDIFENDSCANUSE RETURN,586.00,下列程序统计银行客户关系表中,客户代码的第3、4位的字符是“F8”或“V7”,并且存款金额大于250000元的客户信息和人数。请填空完成。USE 银行客户关系表GOTO TOP_(1)_SCAN _(2)_IF (SUBS(客户代码,3,2)=”F8” OR SUBS(客户代码,3,2)=”V7”)NUM=NUM+1DISPLAYENDIF_(3)_?”满足条件的客户人数有:”,numUSE,num=0(2) For 存款金额250000(3) endscan,