| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1358 人关注过本帖, 2 人收藏
标题:请帮忙,学科成绩尽可能快的排序,谢谢!
只看楼主 加入收藏
schtg
Rank: 12Rank: 12Rank: 12
来 自:Usa
等 级:贵宾
威 望:67
帖 子:1730
专家分:3324
注 册:2012-2-29
收藏
得分:0 
回复 20楼 csyx
我也得研究一下,谢谢!
2023-08-13 19:02
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:707
专家分:2833
注 册:2018-3-13
收藏(1)
得分:6 
前面代码用 SQL 计算排名还是不够快,应该是 sql 没学好,只好改成 vfp 语法,学艺不精啊。
虽然代码多了些,但耗时减少到两秒左右,以空间换时间还是值得的

程序代码:
Close Databases
Use cj In 0
Select xh, dsdm, xqdm, xxdm, kh ;
    ,yw, Cast(0 as I) ywlkx, Cast(0 as I) ywbsx, Cast(0 as I) ywbxx ;
    ,sx, Cast(0 as I) sxlkx, Cast(0 as I) sxbsx, Cast(0 as I) sxbxx ;
    ,yy, Cast(0 as I) yylkx, Cast(0 as I) yybsx, Cast(0 as I) yybxx ;
    from cj into cursor result Readwrite

m.ss = Seconds()
For m.ii = 1 to ALines(aTemp, 'yw,sx,yy', ',')
    m.科目 = aTemp[ii]

? '统计 ' + m.科目 + ' 总排名 ... '
    Select &科目 成绩, 0 分组, Count(*) 人数, Cast(0 as I) 排名 ;
        from result group by 成绩 order by 成绩 desc into cursor temp Readwrite
    SetRank('temp')
    Update t set t.&科目.lkx = s.排名 from result t inner join temp s on t.&科目 = s.成绩

? '统计 ' + m.科目 + ' 市排名 ... '
    Select &科目 成绩, dsdm 分组, Count(*) 人数, Cast(0 as I) 排名 ;
        from result group by 分组, 成绩 order by 分组, 成绩 desc into cursor temp Readwrite
    SetRank('temp')
    Update t set t.&科目.bsx = s.排名 from result t inner join temp s on t.&科目 = s.成绩 and t.dsdm = s.分组

? '统计 ' + m.科目 + ' 乡排名 ... '
    Select &科目 成绩, xqdm 分组, Count(*) 人数, Cast(0 as I) 排名 ;
        from result group by 分组, 成绩 order by 分组, 成绩 desc into cursor temp Readwrite
    SetRank('temp')
    Update t set t.&科目.bxx = s.排名 from result t inner join temp s on t.&科目 = s.成绩 and t.xqdm = s.分组
EndFor
Use in temp

? '总耗时', Seconds() - m.ss
Select result
Locate
Browse

Function SetRank(als)
    Local n分组, n排名
    Select (m.als)
    Locate
    m.n分组 = -1
    Scan all
        If 分组 != m.n分组
            m.n分组 = 分组
            m.n排名 = 1
        EndIf
        Replace next 1 排名 with m.n排名
        m.n排名 = m.n排名 + 人数
    EndScan
EndFunc


把我定义/使用的字段/变量,拼音改成了汉字,这样容易看明白


[此贴子已经被作者于2023-8-14 09:18编辑过]


这家伙很懒,啥也没留下
2023-08-13 20:18
schtg
Rank: 12Rank: 12Rank: 12
来 自:Usa
等 级:贵宾
威 望:67
帖 子:1730
专家分:3324
注 册:2012-2-29
收藏
得分:0 
回复 22楼 csyx
好好,谢谢!
我正在研究、测试,非常感谢!

[此贴子已经被作者于2023-8-14 11:57编辑过]

2023-08-14 05:35
laowan001
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:66
帖 子:1089
专家分:2682
注 册:2015-12-30
收藏(1)
得分:6 
程序代码:
CLOSE DATABASES

LOCAL xfile,xtmpfile,xtime
xtime = SECONDS()
USE cj IN 0
SELECT cj
REPLACE ALL ywlkx WITH 0,ywbsx WITH 0,ywbxx WITH 0,sxlkx WITH 0,sxbsx WITH 0,sxbxx WITH 0,yylkx WITH 0,yybsx WITH 0,yybxx WITH 0

xfile = cjsort('cj','yw')
UPDATE a SET a.ywlkx=b.rec from cj a,&xfile b WHERE a.yw=b.yw
USE IN &xfile

xfile = cjsort('cj','sx')
UPDATE a SET a.sxlkx=b.rec from cj a,&xfile b WHERE a.sx=b.sx
USE IN &xfile

xfile = cjsort('cj','yy')
UPDATE a SET a.yylkx=b.rec from cj a,&xfile b WHERE a.yy=b.yy
USE IN &xfile

* 本市序
SELECT cj
INDEX on dsdm TO cj

xtmpfile = SYS(2015)
SELECT distinct dsdm FROM cj INTO CURSOR &xtmpfile READWRITE 
SELECT &xtmpfile
SCAN 
    SELECT dsdm,yw,sx,yy FROM cj WHERE dsdm=&xtmpfile..dsdm INTO CURSOR &xtmpfile.1 READWRITE 
    xfile = cjsort('&xtmpfile.1','yw')
    UPDATE a SET a.ywbsx=b.rec FROM cj a,&xfile b WHERE a.dsdm=&xtmpfile..dsdm AND a.yw=b.yw
    USE IN &xfile

    xfile = cjsort('&xtmpfile.1','sx')
    UPDATE a SET a.sxbsx=b.rec FROM cj a,&xfile b WHERE a.dsdm=&xtmpfile..dsdm AND a.sx=b.sx
    USE IN &xfile
    
    xfile = cjsort('&xtmpfile.1','yy')
    UPDATE a SET a.yybsx=b.rec FROM cj a,&xfile b WHERE a.dsdm=&xtmpfile..dsdm AND a.yy=b.yy
    USE IN &xfile

    USE IN &xtmpfile.1
ENDSCAN
USE IN &xtmpfile

* 本县序
SELECT cj
INDEX on xqdm TO cj

xtmpfile = SYS(2015)
SELECT distinct xqdm FROM cj INTO CURSOR &xtmpfile READWRITE 
SELECT &xtmpfile
SCAN 
    SELECT xqdm,yw,sx,yy FROM cj WHERE xqdm=&xtmpfile..xqdm INTO CURSOR &xtmpfile.1 READWRITE 

    xfile = cjsort('&xtmpfile.1','yw')
    UPDATE a SET a.ywbxx=b.rec FROM cj a,&xfile b WHERE a.xqdm=&xtmpfile..xqdm AND a.yw=b.yw
    USE IN &xfile
    
    xfile = cjsort('&xtmpfile.1','sx')
    UPDATE a SET a.sxbxx=b.rec FROM cj a,&xfile b WHERE a.xqdm=&xtmpfile..xqdm AND a.sx=b.sx
    USE IN &xfile

    xfile = cjsort('&xtmpfile.1','yy')
    UPDATE a SET a.yybxx=b.rec FROM cj a,&xfile b WHERE a.xqdm=&xtmpfile..xqdm AND a.yy=b.yy
    USE IN &xfile

    USE IN &xtmpfile.1
ENDSCAN
USE IN &xtmpfile


MESSAGEBOX( SECONDS()-xtime)

SELECT * FROM cj 

RETURN

FUNCTION cjsort
LPARAMETERS Pfile,Psortfld
* 返回一个排序的临时文件
LOCAL xfile,xii
xfile = SYS(2015)
SELECT &psortfld,COUNT(*) cnt,CAST(0 AS int) rec FROM &Pfile GROUP BY &psortfld ORDER BY &psortfld DESC INTO CURSOR &xfile READWRITE 
SELECT &xfile
xii = 1
SCAN 
    REPLACE rec WITH xii
    xii = xii + cnt
ENDSCAN
RETURN xfile


22楼计算名次的方法效率很高
修改了16楼的代码后,用时2.5秒
2023-08-14 07:55
schtg
Rank: 12Rank: 12Rank: 12
来 自:Usa
等 级:贵宾
威 望:67
帖 子:1730
专家分:3324
注 册:2012-2-29
收藏
得分:0 
回复 24楼 laowan001
好好,谢谢!
我在消化、测试各位大侠的算法。
非常感谢各位的无私赐教!!!
2023-08-14 11:28
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏(1)
得分:0 
不用SQL也不慢
程序代码:
USE cj
DIMENSION afs[FCOUNT()-5]    && yw及之后的字段名列表
FOR i=6 TO FCOUNT()
    afs[i-5] = FIELD(i)
ENDFOR
USE
cmd = "CREATE CURSOR mc (xh n(9),dsdm n(6),xqdm n(8),xxdm n(10),kh v(16)"
FOR i=1 TO ALEN(afs)
    cmd = cmd + "," + afs[i]+" n(7,1)," + afs[i]+"lkx I," + afs[i]+"bsx I," + afs[i]+"bxx I"
ENDFOR
cmd = cmd + ")"
EXECSCRIPT(cmd)
APPEND FROM cj
tm=SECONDS()
FOR i=1 TO 3 &&ALEN(afs)
    tj_mc(afs[i])
ENDFOR
? SECONDS()-tm
SELECT * FROM mc 
CLOSE TABLES ALL 
RETURN

FUNCTION tj_mc(kmm)
    INDEX on &kmm TAG kmm DESCENDING
    tj_lkx(kmm)    &&联考名次
    INDEX on dsdm*1000+&kmm TAG kmm DESCENDING 
    tj_dsdm(kmm)   &&本市名次   
    INDEX on xqdm*1000+&kmm TAG kmm DESCENDING 
    tj_xqdm(kmm)   &&本县名次
ENDFUNC

FUNCTION tj_lkx(kmm)
    m  = 1
    n  = 1
    fs = -1
    SCAN 
        IF EVALUATE(kmm) != fs
            fs = EVALUATE(kmm)
            m  = n
        ENDIF
        n = n + 1 
        REPLACE (kmm+"lkx") WITH m
    ENDSCAN
ENDFUNC 

FUNCTION tj_dsdm(kmm)
    m  = 1
    n  = 1
    fs = -1
    dm = 0
    SCAN 
        IF dsdm != dm
            dm = dsdm
            m = 1
            n = 1
        ENDIF 
        IF EVALUATE(kmm) != fs
            fs = EVALUATE(kmm)
            m  = n
        ENDIF
        n = n + 1 
        REPLACE (kmm+"bsx") WITH m
    ENDSCAN
ENDFUNC 

FUNCTION tj_xqdm(kmm)
    m  = 1
    n  = 1
    fs = -1
    dm = 0
    SCAN 
        IF xqdm != dm
            dm = xqdm
            m = 1
            n = 1
        ENDIF 
        IF EVALUATE(kmm) != fs
            fs = EVALUATE(kmm)
            m  = n
        ENDIF
        n = n + 1 
        REPLACE (kmm+"bxx") WITH m
    ENDSCAN
ENDFUNC
2023-08-16 10:41
schtg
Rank: 12Rank: 12Rank: 12
来 自:Usa
等 级:贵宾
威 望:67
帖 子:1730
专家分:3324
注 册:2012-2-29
收藏
得分:0 
回复 26楼 吹水佬
谢谢!
2023-08-16 11:37
sdta
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:江苏省连云港市
等 级:版主
威 望:335
帖 子:9841
专家分:27213
注 册:2012-2-5
收藏
得分:0 
回头看,将N科科目分割成N个表,再进行数据处理,速度会提高不少的

坚守VFP最后的阵地
2024-04-07 10:03
快速回复:请帮忙,学科成绩尽可能快的排序,谢谢!
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.033603 second(s), 11 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved