对于数据表,数据采集是手段,利用是目的。对数据最经常的需要就是查询和统计。
本 节 将 学 习 两 种 查 询 方 法 : 顺 序 查 询 和 索 引 查 询 。 相 关 命 令 是 “ LOCATE...
CONTINUE”和“FIND 或 SEEK”。
Visual FoxPro 提供了计数(COUNT)、求和(SUM)、求平均值(AVERAGE)和分类 汇总(TOTAL)等命令,以完成数据统计处理工作。
3.5.1 数据查询
查询是表的一种重要操作。所谓查询,就是在表中查找用户指定条件的记录和字段。在
96 Visual FoxPro 程序设计(第二版)
此之前,通过带条件的 BROWSE、LIST 或 DISPLAY 命令实现简单查询功能,并体会到查 询就是将记录指针定位到所查记录处,再通过显示命令查看数据内容。
1.顺序查询
顺序查找是在表文件中依次查找满足条件的记录。顺序查询也称为直接查询,命令为 LOCATE 和 CONTINUE。
格式:LOCATE [<范围>] [FOR <条件>] [WHILE <条件>]
CONTINUE
功能:LOCATE 命令是在指定范围内查找符合条件的记录。若找到,则将记录指针指向 第一个符合条件的记录;若找不到,指针定位于指定范围的最后记录处。若连续查找,则使 用 CONTINUE 命令,从满足条件的记录的下一条记录开始继续搜索,CONTINUE 可多次使 用,一直到查找完成为止。
说明:
(1)<范围>缺省指 ALL。这对命令配合使用可以进行连续的顺序查找,既可以在索引 文件内进行查找,也可以在表文件内进行查找。对于索引文件,是按索引文件记录的逻辑顺 序进行查找;对于表文件,则按照记录顺序进行查找。
(2)LOCATE 和 CONTINUE 是针对当前工作区而言的,如果选择了另一个工作区,则 原工作区中的查找过程暂被挂起,直到重新选择原来的工作区时,查找过程才可以继续进行。
【例 3.19】在 xsda 表中顺序查找性别为“男”的所有记录。
CLEAR
USE xsgl!xsda.dbf
LOCATE ALL FOR XB="男" &&查找性别为"男"的记录 DISPLAY
格式:FIND <字符串>|<常数>
功能:在一个已建立了索引文件的当前表文件中,查找关键字值与命令行中的<字符串>
或<常数>相匹配的第一个记录。若找到,就停止查找,并将记录指针指向该记录;若没有符
合条件的记录,则函数 FOUND()为.F.,并将当前记录指针指向最后一个记录的后面(函数 EOF()为.T.)。
说明:
1)此命令只能对索引关键字进行查询,且必须在索引文件打开之后使用。
2)FIND 后只能跟 C 型或 N 型的关键字常量。如为 C 型常量,可以省略引号而直接书 写,除非字符串以空格开头或结尾。可查找部分字符串。若查找 N 型或 C 型内存变量,需 用 STR 和 & 函数进行转换。
3)当表中有多个符合条件的记录时,指针定位在第一个,用 SKIP 可定位到下一个。
4)相关函数说明:
当检索到时,FOUND()为.T.,否则为.F.。
当记录指针位于第一个记录的前一个位置时,BOF()为.T.,否则为.F.。
当记录指针位于最后一个记录的后一个位置时,EOF()为.T.,否则为.F.。
【例 3.20】FIND 命令应用举例。
CLEAR
USE xsgl!xsda.dbf &&打开数据库表 xsda
INDEX ON bj TAG 班级 OF xsdabj.cdx &&按 bj 字段建立复合索引文件 xsdabj.cdx LIST && 显示索引后的记录
FIND 机制 991 && 查找班级为机制 991 的记录
?RECNO() && 显示当前记录号
FIND "机制" && 查找班级中含"991"字的记录 DISP
SKIP && 使记录指针定位到下一条符合条件的记录处 DISP
zc1="保险 981" && 将字串常量"保险 981"赋给内存变量 zc1 FIND &zc1 && 查找班级为保险 981 的记录
disp
FIND 930 && 想查找班级为 930 的记录
? FOUND() && 因 bj 关键字中无 930,显示.F.没找到 RETU
运行结果:
98 Visual FoxPro 程序设计(第二版)
(2)SEEK 命令。
格式:SEEK <表达式>
功能:在已打开索引的表文件中快速查找关键字值与<表达式>值相匹配的第一个记录。
说明:
1)<表达式>指定 SEEK 搜索的索引关键字表达式,可查找除 M、G 之外的类型数据,
关键字表达式或其运算值的类型必须与建立索引的表达式类型一致;若<表达式>为内存变量 可直接使用,而无需用函数转换。
2)只能在索引过的表中使用,并且只能对索引关键字进行查询。
3)当表中有多个符合条件的记录时,指针定位在第一个,用 SKIP 可定位到下一个。
4)如果找到,则 RECNO()返回匹配记录的记录号,FOUND()返回.T.,EOF()返回.F.;
如果找不到,则 RECNO()将表中记录的个数加 1,FOUND()返回.F.,EOF()返回.T.。SEEK 的用法与 FIND 基本相同。
【例 3.21】SEEK 命令应用举例。
CLEAR
USE xsgl!xsda.dbf &&打开数据库表 xsda
*按 csrq 和 bj 字段建立复合索引文件 xsda22.cdx INDEX ON csrq TAG 出生日期 OF xsda22.cdx INDEX ON bj TAG 班级 OF xsda22.cdx
SET ORDER TO 出生日期 &&设置标识为“出生日期”的索引为主控索引 DD=CTOD("05/07/82") &&将字串"05/07/82"转换成 D 型数据赋给变量 DD SEEK DD && 查找与日期型变量 DD 之值相匹配的记录 DISP
SET ORDER TO 班级 &&设置标识为“班级”的索引为主控索引
SEEK "保险 981" &&查找班级为“保险 981”的记录,不能写成“SEEK 保险 981”
DISP 运行结果:
3.5.2 数据统计 1.统计记录个数命令
格式:COUNT [<范围>] [FOR <条件>] [TO <内存变量>]
功能:在当前表中统计指定范围内满足条件的记录数。
说明:<范围>缺省指 ALL;TO <内存变量>选项表示把符合条件的记录个数保存到内存 变量中去,不指定内存变量时,结果显示在屏幕上。另外,函数 RECCOUNT()返回当前表
中的记录总数。
【例 3.22】统计 xsda.dbf 表中的全部记录数。
USE xsda.dbf COUNT TO n
USE xsda.dbf
COUNT ALL FOR (xi="机电").AND.(xb="女") TO tmpvar
@ 10,12 SAY "机电系女生人数="
@ 10,29 SAY tmpvar 运行结果:
机电系女生人数= 3 2.求和命令
格式:SUM [<范围>] [<数值表达式表>] [FOR <条件>] [TO <内存变量表>]
功能:在当前表中,对指定范围内给定条件的数值型字段或含数值型字段的数值表达式 进行纵向求和计算。
说明:<范围>缺省指 ALL;<数值表达式表>缺省则对所有数值型字段进行纵向求和;
TO <内存变量表>是将求和的结果依次存入各内存变量中。
【例 3.24】计算数据库表 xsda 中所有学生的入学平均分并显示。
USE xsgl!xsda.dbf
SUM ALL rxf TO fsh &&求入学分总和 COUNT to n &&求人数
STORE fsh/n TO av &&求平均分,并存入变量 av 中
? "平均分=",av PICTURE "9999.99"
运行结果:
平均分= 459.82 3.求平均值命令
格式:AVERAGE [<范围>] [<数值表达式表>] [FOR<条件>] [TO <内存变量表>]
功能:对当前表中的数值型字段或含数值型字段的数值表达式的值按指定范围和条件求 算术平均值。
说明:同 SUM 命令。
【例 3.26】计算数据库表 xsda 中所有学生的入学平均分并显示。
CLEAR
USE xsgl!xsda.dbf AVER ALL rxf TO av
? av 运行结果:
459.82
【例 3.27】求 xsda 表中“男”同学的入学平均分。
100 Visual FoxPro 程序设计(第二版)
CLEAR
USE xsgl!xsda.dbf
AVERAGE ALL rxf FOR xb="男" TO av2
? av2
格式:TOTAL ON <关键字> TO <文件名> [<范围>] [FIELDS <字段名表>] [FOR <条件>]
功能:按关键字对当前表文件的数值型字段进行分类合计,结果存入由本命令新生成的
TOTAL ON xb TO xsdaxb2.dbf FIELDS rxf USE xsdaxb2.dbf
LIST 运行结果:
对照源表文件可以看出,汇总库中仅生成按男、女性别分类的两条记录。这里,分类是 按性别分类,汇总是求同类人员的入学分总和。汇总库中除了被汇总字段的值是同类人员中 该项值之和以外,其他各字段的值是取相同关键字的第一条记录中的内容。
5.财务统计命令 CALCULATE
对表中的字段或包含字段的表达式进行财务和统计操作。
格式:CALCULATE <表达式列表> [范围] [FOR <条件 1>] [WHILE <条件 2>]
[TO <变量列表> | TO ARRAY <数组>]
说明:表达式列表:指定表达式,表达式可以包含下列函数的任意组合:
AVG(<数值型表达式>) CNT()
MAX(<表达式>) MIN(<表达式>) SUM(<数值型表达式>)
注意
用逗号分隔表达式列表中的函数。这些函数仅用于 CALCULATE 命 令。不要与有相似名称的独立函数相混淆,如 CALCULATE MIN()与 MIN() 不同。
【例 3.29】在 xsda.dbf 表中计算学生入学平均分、年龄最大者的生日和总人数。
CALCULATE AVG(rxf), MIN(csrq),CNT() to pjf,zd,zrs
?pjf &&存放入学平均分
?zd &&存放年龄最大者生日
?zrs &&存放学生人数 运行结果:
459.82 11/05/80 17