注册 登录
编程论坛 VFP论坛

各位老师,这段代码错误在哪儿?xx

jinanshui 发布于 2025-01-30 09:26, 1443 次点击
现有一chengji.dbf表,字段为学号,姓名,语文,数学,英语,物理,化学,生物,历史,地理,政治。学号为字符型主字段前2位为年级,3到4位为班级,5到6位为考号,如何求各各年级的各班级的各学科的前45名(按学科成绩排序)的平均分?
最后结果的形式为
年级   班级   语文,数学,英语,物理,化学,生物,历史,地理,政治.

* 创建临时表用于存储结果
CREATE CURSOR result (年级 C(2), 班级 C(2), 语文 N(6,2), 数学 N(6,2), 外语 N(6,2), 物理 N(6,2), 化学 N(6,2), 生物 N(6,2), 历史 N(6,2), 地理 N(6,2), 政治 N(6,2))
* 定义科目数组
DIMENSION aSubjects[9]
aSubjects[1] = "语文"
aSubjects[2] = "数学"
aSubjects[3] = "外语"
aSubjects[4] = "物理"
aSubjects[5] = "化学"
aSubjects[6] = "生物"
aSubjects[7] = "历史"
aSubjects[8] = "地理"
aSubjects[9] = "政治"
* 获取所有不同的年级和班级组合
SELECT DISTINCT SUBSTR(ALLTRIM(学号), 1, 2) AS 年级, SUBSTR(ALLTRIM(学号), 3, 2) AS 班级 ;
FROM chengji ;
INTO CURSOR crsGradeClass
SCAN
    lcGrade = crsGradeClass.年级
    lcClass = crsGradeClass.班级
    LOCAL ARRAY aAvgScores(9)
    aAvgScores = 0
FOR nSubject = 1 TO 9
    lcSubject = aSubjects[nSubject]
* 对每个科目按成绩排序并取前45名的成绩计算平均值
    SELECT 学号, &lcSubject AS score ;
    FROM chengji ;
    WHERE SUBSTR(ALLTRIM(学号), 1, 4) = lcGrade + lcClass ;
    ORDER BY score DESC ;
    INTO CURSOR temp_scores
    IF RECCOUNT() >= 45
        SELECT AVG(score) FROM (SELECT TOP 45 score FROM temp_scores) INTO ARRAY aAvgScore
    ELSE
        SELECT AVG(score) FROM temp_scores INTO ARRAY aAvgScore
    ENDIF
    aAvgScores[nSubject] = aAvgScore[1]
    USE IN temp_scores
ENDFOR
    INSERT INTO result (年级, 班级, 语文, 数学, 外语, 物理, 化学, 生物, 历史, 地理, 政治) ;
    VALUES (lcGrade, lcClass, aAvgScores[1], aAvgScores[2], aAvgScores[3], aAvgScores[4], aAvgScores[5], aAvgScores[6], aAvgScores[7], aAvgScores[8], aAvgScores[9])
ENDSCAN
* 显示结果
SELECT result
BROWSE
9 回复
#2
chychychy2025-01-30 11:08
你这是用哪个Ai写的,附上原数据表测试一下?错误提示是什么?

#3
easyppt2025-01-30 20:00
你要把  chengji  这个表含数据 传上来
#4
my23182025-01-30 20:27
很可能问题出在select语句上
#5
jinanshui2025-01-31 02:37
各位老师,这是数据,请试一试
只有本站会员才能查看附件,请 登录
#6
schtg2025-01-31 08:02
回复 5楼 jinanshui
按一般思路求解,没有验证(好像有班级不足45人,同时第45名有并列情形)。
只有本站会员才能查看附件,请 登录

程序代码:
select *,left(学号,4) as 班级 from chengji into cursor _xscj
cstr = "班级,语文,数学,外语,物理,化学,生物,历史,地理,政治"
=alines(arr,cstr,",")
cfld = "班级 c(5)"
for i = 2 to alen(arr,1)
    cfld = cfld + "," + arr[i] + " n(6,2)"
endfor
select distinct 班级 from _xscj into array abj
create dbf 平均分 (&cfld)
append from array abj
for i = 2 to alen(arr,1)
    select 班级,&arr[i] from _xscj a where 44 >= (select count(*) from _xscj where 班级 = a.班级 and &arr[i] > a.&arr[i]) order by a.班级,a.&arr[i] desc into cursor _cj
    select 班级,avg(&arr[i]) as jf from _cj group by 1 into cursor qb
    update 平均分 set &arr[i] = qb.jf from 平均分,qb where alltrim(平均分.班级)==alltrim(qb.班级)
endfor
select 平均分
go top
browse
close all

#7
chychychy2025-02-02 15:43
回复 楼主 jinanshui
SELECT AVG(score) FROM (SELECT TOP 45 score FROM temp_scores) ;这种嵌套查询的语法是不支持的。需要将查询分成两步来完成:首先获取前45名的成绩,然后计算这些成绩的平均值。
程序代码:
* 创建临时表用于存储结果
CREATE CURSOR result (年级 C(2), 班级 C(2), 语文 N(6,2), 数学 N(6,2), 外语 N(6,2), 物理 N(6,2), 化学 N(6,2), 生物 N(6,2), 历史 N(6,2), 地理 N(6,2), 政治 N(6,2))

* 定义科目数组
DIMENSION aSubjects[9]
aSubjects[1] = "语文"
aSubjects[2] = "数学"
aSubjects[3] = "外语"
aSubjects[4] = "物理"
aSubjects[5] = "化学"
aSubjects[6] = "生物"
aSubjects[7] = "历史"
aSubjects[8] = "地理"
aSubjects[9] = "政治"

* 获取所有不同的年级和班级组合
SELECT DISTINCT SUBSTR(ALLTRIM(学号), 1, 2) AS 年级, SUBSTR(ALLTRIM(学号), 3, 2) AS 班级 ;
FROM chengji ;
INTO CURSOR crsGradeClass

SCAN
    lcGrade = crsGradeClass.年级
    lcClass = crsGradeClass.班级
    LOCAL ARRAY aAvgScores(9)
    aAvgScores = 0

    FOR nSubject = 1 TO 9
        lcSubject = aSubjects[nSubject]

        * 对每个科目按成绩排序并取前45名的成绩
        SELECT TOP 45 &lcSubject AS score ;
        FROM chengji ;
        WHERE SUBSTR(ALLTRIM(学号), 1, 4) = lcGrade + lcClass ;
        ORDER BY score DESC ;
        INTO CURSOR temp_scores

        * 计算前45名成绩的平均值
        SELECT AVG(score) FROM temp_scores INTO ARRAY aAvgScore

        aAvgScores[nSubject] = aAvgScore[1]
        USE IN temp_scores
    ENDFOR

    * 将结果插入到临时表中
    INSERT INTO result (年级, 班级, 语文, 数学, 外语, 物理, 化学, 生物, 历史, 地理, 政治) ;
    VALUES (lcGrade, lcClass, aAvgScores[1], aAvgScores[2], aAvgScores[3], aAvgScores[4], aAvgScores[5], aAvgScores[6], aAvgScores[7], aAvgScores[8], aAvgScores[9])
ENDSCAN

* 显示结果
SELECT result
BROWSE

这是用当下火爆的deepseek修改后的语句,不知道结果是否正确?

[此贴子已经被作者于2025-2-2 15:48编辑过]

#8
chychychy2025-02-02 15:46
回复 6楼 schtg
高效
#9
csyx2025-02-02 19:37
以下是引用chychychy在2025-2-2 15:43:08的发言:
SELECT AVG(score) FROM (SELECT TOP 45 score FROM temp_scores) ;这种嵌套查询的语法是不支持的。需要将查询分成两步来完成:首先获取前45名的成绩,然后计算这些成绩的平均值。

这种嵌套查询 vfp 是支持的,至少 vfp9 支持,没用过 6,也许它不支持,除非为了维护古董,没人用 6 了吧
不过 AI 可能因为不完全了解 vfp 的 sql 语法,写法上有错误
即使是更深的嵌套,vfp9 也支持,temp_scores 都可以省略
程序代码:
* 对每个科目按成绩排序并取前45名的成绩计算平均值
SELECT AVG(score) FROM ( ;
    SELECT TOP 45 score FROM ( ;
        SELECT 学号, 语文 AS score ;
        FROM chengji ;
        WHERE SUBSTR(ALLTRIM(学号), 1, 4) = lcGrade + lcClass ;
    ) a order by score desc) b INTO ARRAY aAvgScore
? aAvgScore[1]
#10
chychychy2025-02-04 15:16
回复 9楼 csyx
原来如此,谢谢,学习了!
1