注册 登录
编程论坛 VFP论坛

求助学生分数段统计

chychychy 发布于 2020-08-30 09:03, 4195 次点击
有数据库1原始学生成绩库(zcj.dbf),主要字段有czxx\czxxdm\bjdm\zf,分别为初中学校、初中学校代码、班级代码、总分等
导出一学校名称表(xxmc.dbf)主要字段有czxxdm\czxx\,分别为初中学校代码、初中学校;简单计算产生一分数段设置表(fsd.dbf)主要字段有N\F1\F2,分别为计数字段、低分字段、高分字段。按照分数段设置和学校名称表内容,统计出各学校相应分数段人数,一种是包含前一分数段,一种是不包含前一分数段
只有本站会员才能查看附件,请 登录

部分学习代码:
select distinct czxxdm  from zcj into table xxmc &&&去重取出所有czxxdm字段,???请教如何同时让xxmc表包含czxx和czxxdm两个字段
select min(zf) df, max(zf) gf from zcj into array fs
ndf=fs[1,1]
ngf=fs[1,2]
ngf=CEILING(ngf/10)*10
fsd=10 && 此处分数段可以更改
zds=CEILING((ngf-ndf)/fsd)+1 && 可设置的字段数,用函数取整
messagebox("当前字段数:"+transform(zds))
F11=ngf &&&&定义变量值
* 创建分数段表
create table fsd (n n(4), f1 n(4,2),f2 n(4,2)) &&&&创建表fsd三个数值型字段N\F1\F2
for i=1 to zds
    insert into fsd values (i,f11-fsd+0.1,f11)
    f11=f11-fsd
endfor
* 创建统计表tjb1一包含前一分数段
???
* 创建统计表tjb2二不包含前一分数段
???
实现下图效果统计数据库
 
只有本站会员才能查看附件,请 登录
24 回复
#2
sdta2020-08-30 10:45
select distinct czxxdm, czxx from zcj into table xxmc
#3
chychychy2020-08-30 10:51
回复 2楼 sdta
谢谢,我之前漏了逗号,后来是中文逗号,怪不得错误。另请教创建统计表tjb1一包含前一分数段代码,之前读过你的其他帖子,主要是命令太复杂,很多我没学过看不懂,请用简单prg指教。

[此贴子已经被作者于2020-8-30 10:54编辑过]

#4
sdta2020-08-30 10:55
* VFP9代码_累加方式(后一分数段人数中包含前一分数段人数)
* 条件:zf >= fsd.f1
程序代码:
CLOSE DATABASES
SELECT MIN(zf), MAX(zf) FROM zcj INTO ARRAY acj
ndf = acj[1, 1]
ngf = acj[1, 2]
nfsd = 10
nzds = CEILING(ngf / nfsd)
IF nzds > 254
    RETURN
ENDIF
* 创建分数段表
CREATE CURSOR fsd (f1 n(4), f2 n(4))
FOR lnj = 1 TO nzds
    INSERT INTO fsd VALUES ((lnj - 1) * nfsd , lnj * nfsd)
ENDFOR
SELECT * FROM fsd WHERE f1 > ndf - nfsd ORDER BY f1 DESC INTO CURSOR fsd
* 创建字段列表
lcStr = "czxx c(50), 人数 n(4)"
SCAN
    lcStr = lcStr + ", ≥F" + PADL(f1, 3, "0") + " n(4)"
ENDSCAN
CREATE CURSOR tjb (&lcStr)
INSERT INTO tjb (czxx, 人数) SELECT czxx, COUNT(*) FROM zcj group by 1
INDEX on czxx TAG name
SELECT czxx, "≥F" + TRANSFORM(fsd.f1) cfsd, COUNT(*) rs FROM zcj, fsd GROUP BY 1, 2 WHERE zf >= fsd.f1 INTO CURSOR cx
SET RELATION TO czxx INTO tjb
SCAN
    REPLACE (cx.cfsd) WITH cx.rs IN tjb
ENDSCAN
SET RELATION TO
SELECT tjb
SET ORDER TO
GO TOP
BROWSE


[此贴子已经被作者于2020-8-30 16:15编辑过]

#5
sdta2020-08-30 11:19
以下是引用chychychy在2020-8-30 10:51:48的发言:

谢谢,我之前漏了逗号,后来是中文逗号,怪不得错误。另请教创建统计表tjb1一包含前一分数段代码,之前读过你的其他帖子,主要是命令太复杂,很多我没学过看不懂,请用简单prg指教。

看不懂不要紧,查VFP帮助文件
#6
chychychy2020-08-30 15:14
回复 4楼 sdta
我将SELECT * FROM fsd WHERE f1 > ndf - nfsd ORDER BY f1 DESC INTO table fsd和CREATE table tjb (&lcStr)中的CURSOR替换后
1.运行REPLACE (cx.cfsd) WITH cx.rs IN tjb
提示找不到变量“≥F0”
测试不包含时
2.运行 lcStr = lcStr + ", ≥F" + PADL(f1, 3, "0") + " n(4)"
提示缺少操作数
3.关于包含不包含我表达的不够清楚,我是想这样:
包含:意思比如实验中学F400(》=400分)统计出有23人,F390(》=390分)有66人,66是包含23的;
不包含:比如实验中学F400(》=400分)统计出有23人,F390(》=390分<400)有43人,43人不包含上一分数段的23人
#7
sdta2020-08-30 16:04
回复 6楼 chychychy
4楼代码已更新
看懂代码的思路后再做修改
别整那些没用的DBF表

[此贴子已经被作者于2020-8-30 18:31编辑过]

#8
sdta2020-08-30 16:13
* VFP9代码_分段方式(后一分数段人数中不包含前一分数段人数)
* 条件:zf >= fsd.f1 AND zf < fsd.f2
程序代码:
CLOSE DATABASES
SELECT MIN(zf), MAX(zf) FROM zcj INTO ARRAY acj
ndf = acj[1, 1]
ngf = acj[1, 2]
nfsd = 10
nzds = CEILING(ngf / nfsd)
IF nzds > 254
    RETURN
ENDIF
* 创建分数段表
CREATE CURSOR fsd (f1 n(4), f2 n(4))
FOR lnj = 1 TO nzds
    INSERT INTO fsd VALUES ((lnj - 1) * nfsd , lnj * nfsd)
ENDFOR
SELECT * FROM fsd WHERE f1 > ndf - nfsd ORDER BY f1 DESC INTO CURSOR fsd
* 创建字段列表
lcStr = "czxx c(50), 人数 n(4)"
SCAN
    lcStr = lcStr + ", ≥F" + PADL(f1, 3, "0") + " n(4)"
ENDSCAN
CREATE CURSOR tjb (&lcStr)
INSERT INTO tjb (czxx, 人数) SELECT czxx, COUNT(*) FROM zcj group by 1
INDEX on czxx TAG name
SELECT czxx, "≥F" + TRANSFORM(fsd.f1) cfsd, COUNT(*) rs FROM zcj, fsd GROUP BY 1, 2 WHERE zf >= fsd.f1 AND zf < fsd.f2 INTO CURSOR cx
SET RELATION TO czxx INTO tjb
SCAN
    REPLACE (cx.cfsd) WITH cx.rs IN tjb
ENDSCAN
SET RELATION TO
SELECT tjb
SET ORDER TO
GO TOP
BROWSE
#9
chychychy2020-08-30 17:00
回复 8楼 sdta
太谢谢了,学习了!
#10
wengjl2020-08-31 16:53
程序代码:
SET ENGINEBEHAVIOR 70
SET SAFETY OFF
SET TALK OFF

CLOSE DATABASES
SELECT 0
USE fsd ALIAS fsd
SELECT 0
USE zcj ALIAS bmk
SELECT fsd
zdgt="( czxxdm c(10),czxx c(30),zrs n(5),"
SCAN
  zdgt=zdgt+fnam+" n(4),"
  SELECT fsd
ENDSCAN
bjg=STUFF(zdgt,RAT(",",zdgt),1,")")  
CREATE TABLE xxk  &bjg.
SELECT czxxdm,czxx,coun(*) as zrs FROM bmk GROUP BY czxxdm INTO CURSOR tmpls
SELECT xxk
APPEND FROM DBF("tmpls")
*-----
SELECT fsd
GO top
SCAN
  _sxf=fsd.f2
  _xxf=fsd.f1
  _zdm=fsd.fnam
  SELECT xxk
  Go top
  SCAN
    _xxdm=xxk.czxxdm
    SELECT bmk
    COUNT TO sn FOR bmk.czxxdm=_xxdm AND bmk.zf>=_xxf AND bmk.zf<_sxf   
    SELECT xxk
    REPLACE (_zdm) WITH sn
  ENDSCAN
  SELECT fsd
ENDSCAN
SELECT xxk
BROWSE


[此贴子已经被作者于2020-8-31 17:00编辑过]

#11
chychychy2020-08-31 17:17
回复 10楼 wengjl
谢谢,学习了。提示找不到“fnam”变量,CREATE TABLE xxk  &bjg.语法错误

[此贴子已经被作者于2020-8-31 17:22编辑过]

#12
wengjl2020-09-01 08:30
我是VF8.0测试通过的,你的是?
#13
chychychy2020-09-01 08:31
回复 12楼 wengjl
Visual FoxPro 9.0
#14
wengjl2020-09-01 08:40
只有本站会员才能查看附件,请 登录

我把你的分数段表中加了一个字段。忘记发上来。你下载覆盖一下
#15
wengjl2020-09-01 08:42
只有本站会员才能查看附件,请 登录
#16
wengjl2020-09-01 08:43
把分数段表修改一下,后一句也是不会有问题了
#17
wengjl2020-09-01 08:44
只有本站会员才能查看附件,请 登录
#18
sdta2020-09-01 12:00
分段方式
只有本站会员才能查看附件,请 登录


累加方式
只有本站会员才能查看附件,请 登录
#19
sdta2020-09-01 12:07
实际上,楼主的问题可以放在一个程序中解决
先解决分段方式的问题,再在分段方式的基础上实现行记录各字段的累加,从而解决累加方式的问题。
#20
chychychy2020-09-01 14:48
回复 17楼 wengjl
谢谢,学习了,下载测试了结果正确。另你这个我测试用了接近15秒。sdta的用了0.3秒,他的确实快。另外象stuff和art函数我平时没用过,正在学习。部分语句含义也正在学习。谢谢指导。
#21
chychychy2020-09-01 14:55
回复 19楼 sdta
确实是,你的代码简洁高效,我正在学习,对我来说两个难题,
一个是创建统计表结构,你巧妙用于lcstr+scan语句解决让我增长不上,
另一个是统计出相应分数段人数并写入我先搬来用了但是没掌握,请再指教说明下

SELECT czxx, "≥F" + TRANSFORM(fsd.f1) cfsd, COUNT(*) rs FROM zcj, fsd GROUP BY 1, 2 WHERE zf >= fsd.f1 AND zf < fsd.f2 INTO CURSOR cx
SET RELATION TO czxx INTO tjb
SCAN
    REPLACE (cx.cfsd) WITH cx.rs IN tjb
ENDSCAN
#22
sdta2020-09-01 15:46
TJB(从表)与CX(主表) 两个临时表建立关联,对程序中不明白的命令可以参考VFP帮助文件。
#23
wengjl2020-09-02 08:25
初学要把重点放在弄清楚代码运算时,在多个表间的转换与取数上(不是追求速度,正如娃娃学步,先走后跑),以及逻辑关系与每个时刻点各表的状态。PRG执行时,虽看不见,但你要想像得出来,A表、B表、C表是如何轮流转换到屏幕的前面来的,或者说想像成三表不动,有一个小机械手是怎样到表中去抓数据的,总之是有一个想像,进步会快一点。但用上SQL,速度快了,机制就想不出来了……
#24
gaoyongbin2020-09-03 20:46
高水平。
#25
chychychy2020-09-15 14:54
回复 23楼 wengjl
有道理,学习了。谢谢!
1