回 帖 发 新 帖 刷新版面

主题:记录合并问题(附件已上传)!!!!!!!!!!!!!!!!!!

我的数据库表中每个人有不同工种的多个证件,而每个证件是一条记录就构成了一人多条记录,

这多条记录的共同点就是“工号”相同。我想在一条记录中显示这个人的多个证件名称,如下:

表1
工号   姓名   工种    证号
001     王     钳工    …….
001     王     汽修    …….
008     李     电工    …….
008     李     木工    …….
008     李     钳工    …….


表2
工号    姓名   工种1    工种2   工种3   工种4
001     王     钳工     汽修
008     李     电工     木工    钳工



注:记录一万多条,工种近60个

恳请帮助!!!!!!!!!!!!!!!!!

回复列表 (共18个回复)

沙发

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

板凳

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 楼

见http://bbs.pfan.cn/post-294050.html

4 楼

回复: wuzhouhong   先谢过老师!按你的程序稍作修改后运行结果如下:

表2
工号    姓名   工种1    工种2   工种3   工种4
001     王     钳工     汽修
008     李     钳工             电工     木工 

注:008的记录中没有工种(汽修)时工种2处有空格,想得到以下结果,也就是一条记录中的两个工种的工种之间无空格

表2
工号    姓名   工种1    工种2   工种3   工种4
001     王     钳工     汽修
008     李     电工     木工    钳工


   

5 楼

你把数据传一个上来,否则我们都是在盲试。

6 楼

哎! 世态炎凉,连个招呼都没挣到一个!

7 楼

楼上两位老师:

附件已上传,压缩包内“表1”为数据库表的一部分;“表2”为需要得到的“多证汇总表”

附件下载:  [url=http://file.pfan.cn/down/bbs/36/20090409585.rar]数据库表[/url]

8 楼

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 楼

说明一下,为什么我要使用如此复杂的操作:

是因为前半截程序生成的是交叉表,很多地方可以使用到这种表。

把“工种”+序号生成的字段名,直接替换成工种名,就是一个典型的交叉表。

10 楼

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

我来回复

您尚未登录,请登录后再回复。点此登录或注册