注册 登录
编程论坛 VFP论坛

请教各位老师,如何求出各种名次

jinanshui 发布于 2023-12-15 02:34, 1027 次点击
老师,学号22--01--01,即年级--班级--学号,如何根据这个成绩表求出----学号  姓名  语文  语文班内名次  语文总名次  .....总分  总分钟名次  总分班内名次,谢谢
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2023-12-15 02:38编辑过]

22 回复
#2
schtg2023-12-15 06:20
回复 楼主 jinanshui
增加字段:alter table 表名 add 字段名 类型(宽度[,小数位] )
年级排名:update 表名 SET 名次字段 = (select count(a.字段名) + 1 from 表名 as a where a.排名字段>zcj.排名字段)
班级排名:update 表名 SET 名次字段 = (select count(a.字段名) + 1 from 表名 as a where a.排名字段>zcj.排名字段 and a.班级字段=zcj.班级字段)
按排名字段循环一下即可。
#3
wengjl2023-12-15 15:57
程序代码:
    * cj_计算名次
    SET SAFETY off
    SET engi 70
    CLOSE DATABASES
    SELECT 0
    USE cj
    SELECT * from cj orde by 总分 desc into cursor temp readw
    SELECT temp
    REPLACE zfmc with RECNO() all
    SELECT temp
    GO top
    SCAN
      SELECT cj
      LOCATE for cj.学号=temp.学号
      IF FOUND()
        REPLACE cj.zfmc with temp.zfmc
      ENDIF
      SELECT temp
    ENDSCAN
    *--
    SELECT bj from cj grou by bj into cursor bjk
    SELECT bjk
    SCAN
      c_bj=bjk.bj
      SELECT * from cj where bj=c_bj orde by 总分 desc into curs ls readw
      SELECT ls
      REPLACE zfbm with RECNO() all
      GO top
      SCAN
        SELECT cj
        LOCATE for cj.学号=ls.学号
        IF FOUND()
          REPLACE cj.zfbm with ls.zfbm
        ENDIF
        SELECT ls
      ENDSCAN
      SELECT ls
      USE
      SELECT bjk
    ENDSCAN
    *--总分的年级名次和班级名次计算完成,学科的计算依次类推(举一反三)
   
    *--代码比较长,但是是最基本的算法。


只有本站会员才能查看附件,请 登录
#4
jinanshui2023-12-15 22:19
谢谢各位老师,我试试。
#5
chychychy2023-12-19 09:21
以总分、和语文为例排列,我只会这样笨一点,如何让语文、数学……自动循环没掌握
程序代码:
SET SAFETY OFF
SELECT *,SPACE(2) 年级,SPACE(2) 班级,0000 总名次,0000 班名次,0000 语文总,0000 语文班 FROM cj INTO CURSOR temp READW
REPLACE 年级 WITH SUBSTR(学号,1,2) ,班级 WITH SUBSTR(学号,3,2) ALL
**分数相同,名次并列
*总分名次
INDEX ON 总分 TAG zfzf DESC
mc=1 &&记录名次
nzf=0 &&记录上条记录总分
nrs=1 &&记录总人数
SCAN
    IF 总分!=nzf
        nzf=总分
        mc=nrs
    ENDIF
    REPLACE 总名次 WITH mc
    nrs=nrs+1
ENDSCAN

* 总分班级名次
INDEX ON 班级-STR(1000-总分) TAG px && 我这样实现了班级升序,总分降序排列
mc=1 && 记录班级名次
nzf=0 && 记录上条记录的总分
cbj="" && 记录班级名称
nrs=1 && 记录班级人数
SCAN
    IF ALLTRIM(班级)!=cbj
        STORE 1 TO nrs,mc
    ELSE
        IF 总分!=nzf
            mc=nrs
        ENDIF
    ENDIF
    REPLACE 班名次 WITH mc
    nrs=nrs+1
    nzf=总分
    cbj=ALLTRIM(班级)
ENDSCAN
* 语文总名次
INDEX ON 年级-STR(1000-语文) TAG px && 我这样实现了班级升序,总分降序排列
mc=1 && 记录班级名次
nzf=0 && 记录上条记录的总分
cbj="" && 记录班级名称
nrs=1 && 记录班级人数
SCAN
    IF ALLTRIM(年级)!=cbj
        STORE 1 TO nrs,mc
    ELSE
        IF 语文!=nzf
            mc=nrs
        ENDIF
    ENDIF
    REPLACE 语文总 WITH mc
    nrs=nrs+1
    nzf=语文
    cbj=ALLTRIM(年级)
ENDSCAN
* 语文班名次
INDEX ON 班级-STR(1000-语文) TAG px && 我这样实现了班级升序,总分降序排列
mc=1 && 记录班级名次
nzf=0 && 记录上条记录的总分
cbj="" && 记录班级名称
nrs=1 && 记录班级人数
SCAN
    IF ALLTRIM(班级)!=cbj
        STORE 1 TO nrs,mc
    ELSE
        IF 语文!=nzf
            mc=nrs
        ENDIF
    ENDIF
    REPLACE 语文班 WITH mc
    nrs=nrs+1
    nzf=语文
    cbj=ALLTRIM(班级)
ENDSCAN

BROWSE



[此贴子已经被作者于2023-12-19 09:29编辑过]

#6
chychychy2023-12-19 09:30
回复 3楼 wengjl
这样总分相同名次不同,一般总分相同名次相同
#7
laowan0012023-12-19 11:45
程序代码:

CLOSE DATABASES

LOCAL xfile,xkc[1],xmc,ii,xfield,xfilemc,xtmpfile,xcj,xbj
xfile = '语文,数学,英语,物理,化学,生物,历史,政治,地理,总分'
ALINES(xkc,xfile,2,',')

xfield = '学号,姓名'
FOR ii=1 TO ALEN(xkc)
    xfield = xfield + ',CAST(0 AS int) ' + xkc[ii] + '班内名次,CAST(0 AS int) ' + xkc[ii] + '总名次'
ENDFOR

xfilemc = SYS(2015)

SELECT *,LEFT(学号,4) bj FROM cj INTO CURSOR &xfilemc

xfile = SYS(2015)    && 排名结果表
SELECT &xfield FROM &xfilemc INTO CURSOR &xfile READWRITE

FOR ii=1 TO ALEN(xkc)
    xfield = xkc[ii]

    xtmpfile = SYS(2015)
    * 班级名次
    SELECT 学号,bj,&xfield FROM &xfilemc ORDER BY bj,&xfield DESC INTO CURSOR &xtmpfile

    xbj = '999999'
    xmc = 0
    xcj = 99999
    SELECT &xtmpfile
    SCAN
        IF bj==xbj        && 同班
        ELSE
            xbj = bj
            xmc = 0
            xcj = 99999
        ENDIF
        
        IF &xfield==xcj        && 成绩相同,名次相同
        ELSE
            xcj = &xfield
            xmc = xmc + 1
        ENDIF
        SELECT &xfile
        REPLACE &xfield.班内名次 WITH xmc FOR 学号=&xtmpfile..学号
        
    ENDSCAN

    xmc = 0
    xcj = 99999
    SELECT * FROM &xtmpfile ORDER BY &xfield DESC INTO CURSOR &xtmpfile
    SCAN         
        IF &xfield==xcj        && 成绩相同,名次相同
        ELSE
            xcj = &xfield
            xmc = xmc + 1
        ENDIF
        SELECT &xfile
        REPLACE &xfield.总名次 WITH xmc FOR 学号=&xtmpfile..学号        
    ENDSCAN
    USE IN &xtmpfile
ENDFOR
USE IN &xfilemc

SELECT * FROM &xfile    && 排名结果
#8
bdx8082023-12-20 09:59
版主这个哪里疏忽了吧,看不懂,提示找不到列'BJ'
#9
chychychy2023-12-20 10:12
回复 8楼 bdx808
SELECT *,LEFT(学号,4) bj FROM cj INTO CURSOR &xfilemc &&&没错啊,这个地方增加了bj字段
#10
chychychy2023-12-20 10:13
回复 7楼 laowan001
b( ̄▽ ̄)d学习了
#11
bdx8082023-12-20 10:39
就是,不好意思啊,我下载的是3楼的附件
#12
jinanshui2023-12-22 11:09
和大家学习,做了一个,大家看看。
CLOSE DATABASES
USE  T2
LOCAL kkb,kkc ,kkd
for kk=1 to 10
       kkb =subs("语文 数学 英语 物理 化学 生物 政治 历史 地理 总分",kk*5-4,4)
       kkc =subs("yw sx yy wl hx sw zz ls dl zf",kk*3-2,2)
kkd=kkc+'zm'
kkc=kkc+'bm'
 ?  kkb,kkc,kkd
alter table t2 add &kkd NUM(4,0) &&增加字段
alter table t2 add &kkc NUM(4,0) &&增加字段
update t2 set &kkd=(select count(a.姓名)+ 1 from T2 as a where a.&kkb>T2.&kkb)
update t2 set &kkc=(select count(a.姓名)+ 1 from T2 as a where a.&kkb>T2.&kkb and a.班级= T2.班级)
endfor
#13
chychychy2023-12-25 17:34
回复 12楼 jinanshui
学习了,建立新字段循环非常简洁高效,值得我学习消化,但是这样同分数名次不相同啊,一般同分名次是相同的,如何进一步解决这个问题
#14
laowan0012023-12-25 19:39
怎么好像楼主换人了啊?到底谁是提问者
#15
chychychy2023-12-26 08:04
回复 14楼 laowan001
我也是爬论坛的学习者
#16
laowan0012023-12-26 11:04
回复 15楼 chychychy
#17
sostemp2023-12-26 11:51
也不知道结果对不对,纯凑个热闹。

圣诞大战-詹姆斯17分塔图姆28+11 浓眉空砍40分湖人负绿军


只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2023-12-26 11:53编辑过]

#18
jinanshui2023-12-27 02:24
17楼老师,十分正确,老师有代码吗?发上来我拜读学习一下,可以吗?
#19
jinanshui2023-12-27 09:43
回复 17楼 sostemp
老师,十分正确,老师有代码吗?发上来我拜读学习一下,可以吗?
#20
老去的流星雨2024-02-20 18:20
数据库不用SQL不是浪费了吗
&&班级名次
SELECT 学号,SUBSTR(学号,3,2) 班级,姓名,语文,00000 as 语文班级名次 FROM cj ORDER BY 班级,语文 DESC INTO CURSOR 语文班级名次 READWRITE
UPDATE 语文班级名次 SET 语文班级名次 = RECNO()
UPDATE 语文班级名次 SET 语文班级名次 = RECNO()-启始 from (SELECT 班级,MIN(语文班级名次)-1 启始 FROM 语文班级名次 GROUP BY 班级) A WHERE 语文班级名次.班级=A.班级
&&全校名次
SELECT 学号,SUBSTR(学号,3,2) 班级,姓名,语文,00000 as 语文全校名次 FROM cj ORDER BY 语文 DESC INTO CURSOR 语文全校名次 READWRITE
UPDATE 语文全校名次 SET 语文全校名次 = RECNO()
只写了语文的,其他类似,最后更新也好,JOIN联接也好
#21
老去的流星雨2024-02-21 08:58
回复 19楼 jinanshui
用了点时间写完了,同分数同名次
LOCAL lcField,lcSQL
lcField = ""
SELECT CJ
FOR m.i= 3 TO 12
    TEXT TO m.lcField ADDITIVE NOSHOW TEXTMERGE
        <<FIELD(m.i)>>,00000 AS <<FIELD(m.i)>>班名次,00000 AS <<FIELD(m.i)>>总名次,
    ENDTEXT
ENDFOR
m.lcSQL = "SELECT 学号,SUBSTR(学号,3,2) AS 班级,姓名,"+LEFT(m.lcField,LEN(m.lcField)-1)+" FROM CJ INTO CURSOR CJPM READWRITE"
EXECSCRIPT(m.lcSQL)
SELECT CJ
FOR m.i= 3 TO 12
    TEXT TO m.lcSQL NOSHOW TEXTMERGE
        SELECT 班级,<<FIELD(m.i)>>,00000 AS <<FIELD(m.i)>>班名次 FROM CJPM GROUP BY 班级,<<FIELD(m.i)>> ORDER BY 班级,<<FIELD(m.i)>> DESC INTO CURSOR TempCursor READWRITE
        UPDATE TempCursor SET <<FIELD(m.i)>>班名次 = RECNO()
        UPDATE TempCursor SET <<FIELD(m.i)>>班名次 = RECNO()-启始 from (SELECT 班级,MIN(<<FIELD(m.i)>>班名次)-1 启始 FROM TempCursor GROUP BY 班级) A WHERE TempCursor.班级=A.班级
        UPDATE CJPM SET <<FIELD(m.i)>>班名次 = TempCursor.<<FIELD(m.i)>>班名次 FROM TempCursor WHERE CJPM.班级 = TempCursor.班级 AND CJPM.<<FIELD(m.i)>> = TempCursor.<<FIELD(m.i)>>
        SELECT <<FIELD(m.i)>>,00000 AS <<FIELD(m.i)>>总名次 FROM CJPM GROUP BY <<FIELD(m.i)>> ORDER BY <<FIELD(m.i)>> DESC INTO CURSOR TempCursor READWRITE
        UPDATE TempCursor SET <<FIELD(m.i)>>总名次 = RECNO()
        UPDATE CJPM SET <<FIELD(m.i)>>总名次 = TempCursor.<<FIELD(m.i)>>总名次 FROM TempCursor WHERE CJPM.<<FIELD(m.i)>> = TempCursor.<<FIELD(m.i)>>
    ENDTEXT
    EXECSCRIPT(m.lcSQL)
    SELECT CJ
ENDFOR
SELECT CJPM
BROWSE

[此贴子已经被作者于2024-2-21 09:35编辑过]

#22
sdta2024-02-21 09:48
回复 21楼 老去的流星雨
施主功力深厚,代码精练,收藏了。

#23
老去的流星雨2024-02-21 15:09
回复 22楼 sdta
共同交流学习
1