Proc SQL连接出现值重复:按callDate区间匹配事件描述的实现问题
核心问题定位
- 分组粒度完全偏离原有数据集粒度:原代码
Group by 1仅按ID单字段分组,但SELECT中包含了snippet1的全量字段(a.*),PROC SQL对非分组、非聚合字段无固定取值规则,会把同一ID下所有连接匹配到的行反复拷贝,直接打破snippet1本身一行一记录的粒度,最终出现大量重复callDate、跨记录乱串的问题。 - 聚合逻辑完全不匹配需求:直接对description取字符串的字典序
min()/max(),完全没有按事件发生的先后顺序(event_date排序)取首/末条有效记录,最终所有分组的聚合结果固定为字典序最小/最大的字符串,和实际业务的事件顺序无关。 - 未过滤空描述干扰:原始
have1中大量description为空的记录会参与连接计算,进一步放大重复行数、干扰聚合结果。
正确实现方案
整体逻辑是严格保留snippet1的原有记录粒度,对每一条原记录独立匹配对应日期区间内的有效事件,按事件日期的先后顺序取首、末条有效描述。
- 先预处理事件表,过滤掉无有效描述的空行,减少无效计算:
data have1_valid; set have1; where strip(description) ne ''; * 仅保留有实际描述的有效事件; by id event_date; run;
- 对
snippet1的每一行独立匹配对应区间的事件,取按日期排序后的首条和末条描述:
proc sql; create table want as select a.*, * 取callDate到callDate+2天区间内,按event_date最早的有效描述作为description1 * (select c.description from have1_valid c where c.id = a.id and c.event_date between a.calldate and a.calldate+2 order by c.event_date having c.event_date = min(c.event_date) ) as description1, * 取callDate到callDate+2天区间内,按event_date最晚的有效描述作为description2 * (select c.description from have1_valid c where c.id = a.id and c.event_date between a.calldate and a.calldate+2 order by c.event_date having c.event_date = max(c.event_date) ) as description2 from snippet1 a order by a.id, a.callDate; quit;
注:上述实现完全不会改变
snippet1的原有记录数量,不会出现重复行,匹配逻辑完全对齐需求:以callDate为起点,向后2天范围内的有效事件,按实际发生日期排序取最早、最晚的描述值。比如callDate为2020-12-02时,匹配区间是2020-12-02到2020-12-04,范围内最早的有效事件是12-02的OLd Contact Strategy Level,最晚的是12-04的Review Date,和需求示例完全一致。
内容的提问来源于stack exchange,提问作者amestrian
相关产品推荐
相关产品推荐

