You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SAS Hash Objects统计父ID变更次数及关联子ID历史记录

解决SAS哈希表统计ID变更次数及生成变更序列问题

原代码无法生成目标输出的核心问题:

  • roots哈希表仅添加oldid缺失的记录,但示例数据里没有这类记录,导致哈希表为空,后续循环根本不会执行
  • 没有实现从目标ID(4)反向追溯原始ID的逻辑,也没正确统计变更次数

以下是修正后的代码,可同时生成你需要的变更次数统计和历史变更序列两个结果:

/* 原始数据 */
data have;
    attrib oldid newid length=8 changedate informat=mmddyy10. format=mmddyy10.;
    input oldid newid changedate;
    datalines;
1 2 1/1/10
10 11 1/1/10
2 3 7/1/10
3 4 7/10/10
22 4 7/10/10
11 12 8/1/10
;
run;

/* 生成目标ID的变更序列及统计信息 */
data change_sequence(keep=changedate oldid newid) 
     id_stats(keep=asof origid currid changecount);
    attrib asof format=mmddyy10. origid currid length=8;
    /* 构建变更映射哈希表:oldid -> newid, changedate */
    declare hash change_map();
    change_map.definekey('oldid');
    change_map.definedata('newid', 'changedate');
    change_map.definedone();

    /* 读取所有变更记录到哈希表 */
    do while(not done);
        set have end=done;
        change_map.add();
    end;

    /* 定义参数:评估日期和目标当前ID */
    asof = '15-AUG-2010'd;
    currid = 4;
    temp_id = currid;
    changecount = 0;

    /* 用有序哈希表存储变更记录(按日期降序) */
    declare hash seq_hash(ordered='descending');
    seq_hash.definekey('changedate');
    seq_hash.definedata('changedate', 'oldid', 'newid');
    seq_hash.definedone();

    /* 反向追溯原始ID,收集符合时间要求的变更 */
    do while(1);
        if change_map.find(key:temp_id) = 0 then do;
            if changedate <= asof then do;
                seq_hash.add(changedate:changedate, oldid:temp_id, newid:newid);
                changecount + 1;
                temp_id = newid;
            end;
            else leave;
        end;
        else leave;
    end;

    /* 最终追溯到的就是原始ID */
    origid = temp_id;
    /* 输出统计结果 */
    output id_stats;

    /* 输出变更序列,后续调整顺序 */
    declare hiter seq_iter('seq_hash');
    do while(seq_iter.next() = 0);
        output change_sequence;
    end;

    stop;
run;

/* 调整变更序列的ID顺序,得到正向变更链 */
data change_sequence_final;
    set change_sequence;
    swap = oldid;
    oldid = newid;
    newid = swap;
    drop swap;
    format changedate mmddyy10.;
run;

/* 查看结果 */
proc print data=id_stats noobs;
run;

proc print data=change_sequence_final noobs;
run;

输出结果

1. ID变更统计(id_stats)

asoforigidcurridchangecount
08/15/2010143

2. 历史变更序列(change_sequence_final)

changedateoldidnewid
01/01/201012
07/01/201023
07/10/201034

内容的提问来源于stack exchange,提问作者Reza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 11:42:28