主题:记录合并问题(附件已上传)!!!!!!!!!!!!!!!!!!
tsfdg
[专家分:530] 发布于 2009-04-02 16:45:00
我的数据库表中每个人有不同工种的多个证件,而每个证件是一条记录就构成了一人多条记录,
这多条记录的共同点就是“工号”相同。我想在一条记录中显示这个人的多个证件名称,如下:
表1
工号 姓名 工种 证号
001 王 钳工 …….
001 王 汽修 …….
008 李 电工 …….
008 李 木工 …….
008 李 钳工 …….
表2
工号 姓名 工种1 工种2 工种3 工种4
001 王 钳工 汽修
008 李 电工 木工 钳工
注:记录一万多条,工种近60个
恳请帮助!!!!!!!!!!!!!!!!!
最后更新于:2009-04-09 15:23:00
回复列表 (共18个回复)
沙发
wuzhouhong [专家分:10890] 发布于 2009-04-02 18:16:00
LOCAL nXCount,aXList(1),I,aFieldsList(1),cFieldName,aCheck(1)
SET TALK OFF
CLEAR
SELECT distinc 工种 FROM test.dbf INTO ARRAY aXList
IF VARTYPE(aXList(1))="C" && 检测到至少存在一个工种
m.nXCount=ALEN(aXList,1) && 工种个数
ELSE
m.nXCount=0
ENDIF
CLOSE DATABASES ALL && 关掉无用的表
IF m.nXCount=0
RETURN MESSAGEBOX("没有任何工种,无法处理")
ENDIF
CREATE CURSOR TempTable (工号 Char(10),姓名 Char(10),证号 Char(10)) && 建临时表
DIMENSION aFieldsList(m.nXCount,2) && 字段名-工种名对照表
FOR m.I=1 TO m.nXCount && 添加新字段,同时处理字段名-工种名对照表
aFieldsList(m.I,1)="工种"+ALLTRIM(STR(m.I)) && 字段名
aFieldsList(m.I,2)=aXList(m.I) && 工种名
ALTER TABLE TempTable ADD COLUMN (aFieldsList(m.I,1)) CHAR(10) && 添加新字段
ENDFOR
*** 开始处理
SELECT 0
USE test.dbf ALIAS TEST SHARED
SCAN
FOR m.I=1 TO m.nXCount && 按工种在对照表中查找相应字段名
IF TEST.工种=aFieldsList(m.I,2)
m.cFieldName=aFieldsList(m.I,1) && 找到了对应字段名
EXIT
ENDIF
ENDFOR
*** 写入
SELECT CNT(*) FROM TempTable WHERE TempTable.工号=TEST.工号 INTO Array aCheck && 查询目标表是否存在相应记录
IF aCheck(1)=0 && 没有,则新建记录
INSERT INTO TempTable (工号,姓名,证号) VALUES (TEST.工号,TEST.姓名,TEST.证号)
ENDIF
UPDATE TempTable SET &cFieldName=TEST.工种 WHERE TempTable.工号=TEST.工号
ENDSCAN
SELECT TempTable
BROWSE
板凳
jinlonggao [专家分:17130] 发布于 2009-04-02 18:42:00
select 0
select 工号,姓名,count(*) as 证件数 from 表1 group by 工号,姓名 into cursor cc1
select 0
select max(证件数) as 最多证件数 from cc1 into cursor cc2
n = 最多证件数
fStr = ','
for i = 1 to n
fStr = fStr + '工种'+alltr(str(i))+' C(6)'
endfor && 结果类似于:" ,工种1 C(6),工种2 C(6),..."
create table 结果表 ( 工号 C(3),姓名 C(8),&fStr.) &&定义"结果表"
select cc1
scan
gh = 工号
fStr = '工号,姓名,'
vStr = '"'工号+'","' + 姓名 +'"'
for i = 1 to 证件数
fStr = fStr + '工种'+ alltr(str(i))
endfor
select 表1
set filter to 工号 = gh
scan
vStr = vStr + ',"'+工种+'"'
endscan
inser into 结果表 (&fStr.) values(&vStr.)
select cc1
endscan
3 楼
狐说八道 [专家分:860] 发布于 2009-04-06 09:19:00
见http://bbs.pfan.cn/post-294050.html
4 楼
tsfdg [专家分:530] 发布于 2009-04-08 15:55:00
回复: wuzhouhong 先谢过老师!按你的程序稍作修改后运行结果如下:
表2
工号 姓名 工种1 工种2 工种3 工种4
001 王 钳工 汽修
008 李 钳工 电工 木工
注:008的记录中没有工种(汽修)时工种2处有空格,想得到以下结果,也就是一条记录中的两个工种的工种之间无空格
表2
工号 姓名 工种1 工种2 工种3 工种4
001 王 钳工 汽修
008 李 电工 木工 钳工
5 楼
wuzhouhong [专家分:10890] 发布于 2009-04-09 09:34:00
你把数据传一个上来,否则我们都是在盲试。
6 楼
jinlonggao [专家分:17130] 发布于 2009-04-09 10:39:00
哎! 世态炎凉,连个招呼都没挣到一个!
7 楼
tsfdg [专家分:530] 发布于 2009-04-09 15:15:00
楼上两位老师:
附件已上传,压缩包内“表1”为数据库表的一部分;“表2”为需要得到的“多证汇总表”
附件下载: [url=http://file.pfan.cn/down/bbs/36/20090409585.rar]数据库表[/url]
8 楼
wuzhouhong [专家分:10890] 发布于 2009-04-09 18:39:00
LOCAL nXCount,aXList(1),I,J,aFieldsList(1),cFieldName,aCheck(1),aResult(1),nMax,K
SET TALK OFF
CLEAR
SELECT distinc 工种 FROM test.dbf INTO ARRAY aXList
IF VARTYPE(aXList(1))="C" && 检测到至少存在一个工种
m.nXCount=ALEN(aXList,1) && 工种个数
ELSE
m.nXCount=0
ENDIF
CLOSE DATABASES ALL && 关掉无用的表
IF m.nXCount=0
RETURN MESSAGEBOX("没有任何工种,无法处理")
ENDIF
CREATE CURSOR TempTable (工号 Char(10),姓名 Char(10),证号 Char(10)) && 建临时表
DIMENSION aFieldsList(m.nXCount,2) && 字段名-工种名对照表
FOR m.I=1 TO m.nXCount && 添加新字段,同时处理字段名-工种名对照表
aFieldsList(m.I,1)="工种"+ALLTRIM(STR(m.I)) && 字段名
aFieldsList(m.I,2)=aXList(m.I) && 工种名
ALTER TABLE TempTable ADD COLUMN (aFieldsList(m.I,1)) CHAR(10) && 添加新字段
ENDFOR
*** 开始处理
SELECT 0
USE test.dbf ALIAS TEST SHARED
SCAN
FOR m.I=1 TO m.nXCount && 按工种在对照表中查找相应字段名
IF TEST.工种=aFieldsList(m.I,2)
m.cFieldName=aFieldsList(m.I,1) && 找到了对应字段名
EXIT
ENDIF
ENDFOR
*** 写入
SELECT CNT(*) FROM TempTable WHERE TempTable.工号=TEST.工号 INTO Array aCheck && 查询目标表是否存在相应记录
IF aCheck(1)=0 && 没有,则新建记录
INSERT INTO TempTable (工号,姓名,证号) VALUES (TEST.工号,TEST.姓名,TEST.证号)
ENDIF
UPDATE TempTable SET &cFieldName=TEST.工种 WHERE TempTable.工号=TEST.工号
ENDSCAN
SELECT TempTable
*** 在原来数据基础继续处理
DIMENSION aResult(m.nXCount,2) && 定义排序用数组
FOR m.I=1 TO m.nXCount && 字段名表生成一下
aResult(m.I,1)="工种"+ALLTRIM(STR(m.I))
ENDFOR
m.nMax=0
SCAN
FOR m.I=1 TO m.nXCount
aResult(m.I,2)=EVALUATE(aResult(m.I,1)) && 装入数据
ENDFOR
m.K=0 && 本条记录的非空工种个数
FOR m.I=1 TO m.nXCount && 非空,位置前移
IF !EMPTY(aResult(m.I,2))
m.K=m.K+1
FOR m.J=1 TO m.nXCount
IF EMPTY(aResult(m.J,2)) && ,空,则置入
aResult(m.J,2)=aResult(m.I,2)
aResult(m.I,2)=""
EXIT
ENDIF
ENDFOR
ENDIF
ENDFOR
m.nMax=MAX(m.nMax,m.K) && 计算每行的最大非空工种个数
FOR m.I=1 TO m.nXCount && 写入
REPLACE (aResult(m.I,1)) WITH aResult(m.I,2)
ENDFOR
ENDSCAN
**删除已经不必要的字段
FOR m.I=m.nXCount TO m.nMax+1 STEP -1
ALTER table TempTable DROP COLUMN (aResult(m.I,1))
ENDFOR
BROWSE
9 楼
wuzhouhong [专家分:10890] 发布于 2009-04-09 18:44:00
说明一下,为什么我要使用如此复杂的操作:
是因为前半截程序生成的是交叉表,很多地方可以使用到这种表。
把“工种”+序号生成的字段名,直接替换成工种名,就是一个典型的交叉表。
10 楼
qjbzjp [专家分:8830] 发布于 2009-04-10 19:04:00
USE 表1
SET ENGINEBEHAVIOR 70
SELECT * FROM 表1 GROUP BY 1 INTO CURSOR cursor1
COPY TO mycursor
USE mycursor IN 0 excl
ALTER TABLE mycursor drop column 工种
ALTER table mycursor ADD COLUMN 工种1 C(7)
ALTER table mycursor ADD COLUMN 工种2 C(7)
ALTER table mycursor ADD COLUMN 工种3 C(7)
ALTER table mycursor ADD COLUMN 工种4 C(7)
ALTER table mycursor ADD COLUMN 工种5 C(7)
SELECT 表1
FOR i=1 TO RECCOUNT("mycursor")
GO i IN mycursor
SET FILTER TO 工号=mycursor.工号
SCAN
DO CASE
CASE EMPTY(ALLTRIM(mycursor.工种1))
REPLACE mycursor.工种1 WITH 表1.工种
CASE EMPTY(ALLTRIM(mycursor.工种2))
REPLACE mycursor.工种2 WITH 表1.工种
CASE EMPTY(ALLTRIM(mycursor.工种3))
REPLACE mycursor.工种3 WITH 表1.工种
CASE EMPTY(ALLTRIM(mycursor.工种4))
REPLACE mycursor.工种4 WITH 表1.工种
CASE EMPTY(ALLTRIM(mycursor.工种5))
REPLACE mycursor.工种5 WITH 表1.工种
ENDCASE
ENDSCAN
NEXT
SELECT mycursor
brow
我来回复