主题:一堆杂乱无章的数,如何统计出现的次数,代码应如何写呢,请高手支招
icbccom
[专家分:0] 发布于 2009-11-09 13:37:00
DBF表----A1
-----------------------------------------------------------------
表名 | 参数
P0001 | 29,24,35,02,34,20,31,36,10,09,25,14,28,01,26,23,15,33,
P0002 | 08,19,20,11,01,02,35,03,16,23,27,34,32,29,25,30,12,22,
P0003 | 26,21,11,22,16,24,12,27,33,13,15,18,04,05,19,02,03,31,
P0004 | 29,34,32,27,07,16,01,25,08,30,22,18,35,23,31,11,06,12,
P0005 | 04,14,05,06,08,21,17,01,36,34,13,22,03,23,33,24,25,30,
...... 共有1万条记录
-----------------------------------------------------------------
现在需要从A1表中取出 多张表(如8张) 来统计各数值出现的次数,代码应如何写呢,请高手支招。
需要的结论如下(举例):
8次: 20
5次:01,12,15
3次:03,04,09,23,29,33,35,36
2次:06,07,11,16,19
1次: …
0次:…
回复列表 (共28个回复)
11 楼
cbl518 [专家分:57140] 发布于 2009-11-17 17:49:00
5:再用 sql 查询语句分组统计数量即可!
12 楼
cbl518 [专家分:57140] 发布于 2009-11-17 17:50:00
最后将同样数量的元素再统计在一起!
13 楼
icbccom [专家分:0] 发布于 2009-11-18 14:11:00
[quote]用 OCCURS 函数统计太慢了!!![/quote]
谢谢诸位的解答,本人非常感激!
用 OCCURS 函数统计确实很慢,能否再次赐教具体SQL代码的写法!
14 楼
Vii [专家分:1130] 发布于 2009-11-18 16:51:00
SELECT SUM(OCCURS('40',参数)) as 参数个数 FROM A1
这样不是可以吗?费时0.05秒.
难道我理解错了?
顺便问下,lz是不是参数里各个不一样的数字(1,2,33,45...),全部一次性都汇总出来各有多少个?而不是像我上面这样指定查找某个数字有多少?
请明确.
15 楼
Vii [专家分:1130] 发布于 2009-11-18 17:44:00
CLOSE ALL
SET SAFETY OFF
zf=''
CREATE TABLE Temp_Test(tablename c(10),cs c(150))
CREATE TABLE Temp_Test1(cc c(10))
FOR i = 1 TO 10000
cStr=''
FOR n= 1 TO 18
cStr=cStr+PADL(ALLTRIM(STR(INT(RAND()*99))),2,'0')+','
ENDFOR
INSERT INTO Temp_test(tablename,cs) VALUES ('P00'+aLLTRIM(STR(i)),cStr)
ENDFOR
FOR h= 1 TO 100
zf=PADL(alltrim(STR(h)),2,'0')
INSERT INTO Temp_Test1(cc) VALUES (zf)
ENDFOR
tt=SECONDS()
*SELECT * FROM Temp_test1,Temp_Test
*SELECT SUM(gs) FROM (SELECT cc,SUM(OCCURS(ALLTRIM(cc),cs)) as gs FROM Temp_test1 a,Temp_test b GROUP BY cc) a
[color=FF0000]SELECT cc,SUM(OCCURS(ALLTRIM(cc),cs)) as gs FROM Temp_test1 a,Temp_test b GROUP BY cc INTO CURSOR tmp[/color]
?SECONDS()-tt
这样每个数据都去统计出来,我设计了参数有100个不同的.
费时10秒++.也没去找有没有其他类似OCCURS的函数.
win2008,vfp9,2G内存.
16 楼
icbccom [专家分:0] 发布于 2009-11-18 18:01:00
[quote]SELECT SUM(OCCURS('40',参数)) as 参数个数 FROM A1
这样不是可以吗?费时0.05秒.
难道我理解错了?
顺便问下,lz是不是参数里各个不一样的数字(1,2,33,45...),全部一次性都汇总出来各有多少个?而不是像我上面这样指定查找某个数字有多少?
请明确.[/quote]
谢谢VII网友的答复。这代码:SELECT SUM(OCCURS('01',参数)) as 参数个数 FROM A1
好似得出的结果=0
需要的是用SQL方式实现:
第一步:所有表记录中“参数”合并在一起。即 P0001--P..X各参数合并成“29,24,35... ..."
第二步:统计出号码“1-36"在所有“参数”中出现的次数。
--------------------------------------------------------
以下为cbl518帮忙提供的设计思路,但实现起来仍很慢。不知道还能有其他办法不?
sele A1
COPY TO FileName.dat FIELDS 参数 sdf
?OCCURS('01',CHRTRAN(FILETOSTR("FileName.dat"),CHR(10)+" "+CHR(13),"") )
这样我还得循环36次,慢。但对于我这个水平的人已经很受用了,在此向 cbl518 致敬!
17 楼
Vii [专家分:1130] 发布于 2009-11-18 18:28:00
如果说循环的话,我14楼的代码肯定是可以的。
包括15楼的代码。
如果你去循环几次查询,那这个问题已经变的很好处理了。
如果100个参数改为36个,15楼的查询在5秒内。
因为15楼的代码,实际表数据由10000增加到了1000000,我估计36个参数去循环查询后组合到一张表,比这样直接分组查询还要快。未测试。
经过测试:循环36次查询汇总成为一张表耗时1.5秒左右,直接将原表文件10000连接为360000查询汇总耗时:4.4秒左右.
18 楼
cbl518 [专家分:57140] 发布于 2009-11-18 19:10:00
你把所有的数据表上传,我再给你写代码!
按经验来讲,这些数据应该在毫秒馁,就可以解决了!
19 楼
Vii [专家分:1130] 发布于 2009-11-18 20:40:00
CLOSE ALL
CLEAR
SET SAFETY OFF
zf=''
bjz=''
CREATE TABLE Temp(tablename c(10),cs c(110))
CREATE TABLE Temp1(c c(2))
CREATE TABLE TMP_RE(c c(2),n n)
FOR i = 1 TO 10000
cStr=''
FOR n= 1 TO 36
cStr=cStr+PADL(ALLTRIM(STR(INT(RAND()*35+1))),2,'0')+','
ENDFOR
INSERT INTO Temp(tablename,cs) VALUES ('P00'+aLLTRIM(STR(i)),cStr)
ENDFOR
FOR h= 1 TO 36
zf=PADL(alltrim(STR(h)),2,'0')
INSERT INTO Temp1(c) VALUES (zf)
ENDFOR
t=SECONDS()
SELECT Temp1
FOR m= 1 TO 36
GO m
bjz=ALLTRIM(c)
INSERT INTO Tmp_re(c,n) SELECT bjz,SUM(OCCURS(bjz,cs)) FROM Temp
ENDFOR
?'循环查询花费:',SECONDS()-t,'秒'
SELECT Tmp_re
BROWSE
t=SECONDS()
SELECT c,SUM(OCCURS(ALLTRIM(c),cs)) as gs FROM Temp1 a,Temp b GROUP BY c INTO CURSOR Tmp
?'汇总查询花费:',SECONDS()-t,'秒'
SELECT Tmp
BROWSE
最新的测试代码,10000行记录,36个参数.
循环查询花费:1.735秒
汇总查询花费:2.625秒
希望lz把数据放上来.以便测试.
[em4][em4]
20 楼
cbl518 [专家分:57140] 发布于 2009-11-18 23:27:00
按你给的数据
CREATE CURSOR Temp(tablename c(10),参数 c(110))
FOR i = 1 TO 10000
cStr=''
FOR n= 1 TO 36
cStr=cStr+PADL(ALLTRIM(STR(INT(RAND()*35+1))),2,'0')+','
ENDFOR
INSERT INTO Temp(tablename,参数) VALUES ('P00'+aLLTRIM(STR(i)),cStr)
ENDFOR
用直接分组查询我试了一下是 0.8 秒!!!
我来回复