注册 登录
编程论坛 VFP论坛

如何多条件遍历全表

sharpex1 发布于 2024-04-25 18:03, 292 次点击
有个40万基础表,里面有号码,地址,用户ID,在用APP,在用硬件,希望判断两个号码是否是同一个人,思路是,每行的号码两两比较 用户ID相同,那么给个0.3系数,如果地址相同,给个0.2系数,如果在用APP相同,给个0.1系数,在用硬件相同,给个0.1系数,当所有系数加起来大于0.5,那么两个号码是同一个人,这个时候给两个号码 赋予相同的 客户编号,比如A1,后面可以通过客户编号就能筛选出哪些号码可能是同一个人,难点是系数求和只能是对比的同一行号码对应的,跨行的话系数求和就不对了,所以做了逐行比较,但是40万数据根本运行不了,会卡死,求教
只有本站会员才能查看附件,请 登录

程序代码:

* 打开基础表格
USE 号码归属客户判断

* 创建客户编码计数器
lnCustomerCount = 1

* 遍历表格数据,从第一行开始比较到倒数第二行
FOR lnRow = 1 TO RECCOUNT() - 1
    * 定位到当前行
    GO lnRow

    * 获取当前行的地址、用户ID和合户代付群主ID
    lcCurrentAddress = Address
    lcCurrentUserID = UserID
    lcCurrentGroupID = GroupOwnerID
    lnCurrentCustomerNum = CustomerNum  && 当前行的客户编码

    * 初始化系数
    lnAddressFactor = 0
    lnUserFactor = 0
    lnGroupFactor = 0

    * 从下一行开始比较
    FOR lnNextRow = lnRow + 1 TO RECCOUNT()
        * 定位到下一行
        GO lnNextRow

        * 获取下一行的地址、用户ID和合户代付群主ID
        lcNextAddress = Address
        lcNextUserID = UserID
        lcNextGroupID = GroupOwnerID

        * 计算地址系数
        IF lcCurrentAddress = lcNextAddress
            lnAddressFactor = 0.3
        ENDIF

        * 计算用户系数
        IF lcCurrentUserID = lcNextUserID
            lnUserFactor = 0.2
        ENDIF

        * 计算合户系数
        IF lcCurrentGroupID = lcNextGroupID
            lnGroupFactor = 0.2
        ENDIF

        * 判断系数之和是否大于等于0.7,如果是则分配客户编码
        IF lnAddressFactor + lnUserFactor + lnGroupFactor >= 0.7
            IF EMPTY(lnCurrentCustomerNum)
                lcNewCustomerNum = "A" + TRANSFORM(lnCustomerCount)
                lnCustomerCount = lnCustomerCount + 1
                * 使用 SCAN ... ENDSCAN 结构来更新客户编码字段
                SCAN
                    IF RECNO() = lnRow OR RECNO() = lnNextRow
                        REPLACE CustomerNum WITH lcNewCustomerNum
                    ENDIF
                ENDSCAN
            ELSE
                * 更新下一行的客户编码字段
                REPLACE CustomerNum WITH lnCurrentCustomerNum FOR RECNO() = lnNextRow
            ENDIF
        ENDIF
    ENDFOR
NEXT

* 关闭基础表格
USE IN 号码归属客户判断
10 回复
#2
yiyanxiyin2024-04-25 18:24
必须id相同才可能大于0.5, 所以按id进行关联, 速度应该不是问题了
#3
my23182024-04-26 08:30
逐条比较虽然简单但效率太低,应该建索引然后查找,,效率要好些
#4
csyx2024-04-26 08:53
你设计的算法可能有问题
你只用了 用户ID(0.3)、地址(0.2)、在用APP(0.1)、在用硬件(0.1) 四个字段计算系统,那么就算后面三项都相同,其系数和也只有 0.4,不可能满足 >= 0.5 的要求
换句话说,判断是否同一客户的最小条件就是至少【用户ID】要相同
而从你提供的 1w 条验证数据来看,除了用户ID为'0'的记录以外,其他行的用户ID都是唯一的。换言之,你只需要比较【用户ID】= '0'的记录即可,其他不可能满足 >= 0.5 的条件
#5
sharpex12024-04-26 09:45
回复 2楼 yiyanxiyin
这里只是个举例,实际判断有十几个字段
#6
sharpex12024-04-26 09:50
回复 4楼 csyx
这里只是个举例,实际判断有十几个字段
#7
yiyanxiyin2024-04-26 15:59
长时间执行的任务可以使用多线程, 一次大循环完成就表示处理完成一条数据,并把处理完成的数据总量输出, 以便观察整个任务的执行进度.
#8
sharpex12024-04-26 16:47
回复 7楼 yiyanxiyin
求指导啊。。具体代码怎么实现
#9
吹水佬2024-04-26 17:30
按ID+地址索引后遍历一次表应该就可以
#10
sharpex12024-04-26 17:52
回复 9楼 吹水佬
无耻求代码
#11
吹水佬2024-04-26 21:47
以下是引用sharpex1在2024-4-26 17:52:13的发言:

无耻求代码

试试,不知有无理解错
程序代码:

USE 号码归属客户判断 ALIAS tt1 IN 0
USE 号码归属客户判断 ALIAS tt2 AGAIN IN 0
SELECT tt1
INDEX on 身份证id+地址+在用app TAG tag1
SELECT tt2
SET RELATION TO 身份证id+地址+在用app INTO "tt1"
SCAN
    IF FOUND("tt1") AND RECNO("tt1")!=RECNO("tt2") AND !EMPTY(tt2.在用app) && 假设空视为无效
        ? RECNO("tt1"),tt1.身份证id,tt1.地址,tt1.在用app     && >0.5视为重复记录
        ? RECNO("tt2"),tt2.身份证id,tt2.地址,tt2.在用app
        ?
    ENDIF
ENDSCAN

同理可查找 身份证id+地址+硬件

1