使用PROC SQL左连接匹配每行最近日期时重复数据问题求助
问题分析与解决方案
你的代码出现重复数据的核心原因是**group by子句包含了b.date**:当你把b.date加入分组字段后,每个不同的b.date都会被单独分组,having b.date = max(b.date)的条件其实等价于保留每个分组的所有记录(因为每个分组的max(b.date)就是该组自身的b.date),根本没起到筛选“最近日期”的作用,所以会保留所有满足datepart(a.date)>=datepart(b.date)的匹配记录,导致重复。
下面提供两种可靠的解决方法:
方法一:先筛选每个用户的最近符合条件日期,再关联
先通过子查询找出每个username在table2中满足datepart(b.date) <= datepart(a.date)的最大日期,再用这个结果和原表关联,避免提前产生大量匹配:
proc sql; create table table3 as select a.*, b.* from table1 as a left join ( select username, max(date) as max_date from table2 group by username ) as b_max on a.username = b_max.username left join table2 as b on b.username = b_max.username and datepart(b.date) = datepart(b_max.max_date) and datepart(b.date) <= datepart(a.date); quit;
如果同一个用户在table2中存在多个相同最大日期的记录,会保留所有这些记录;如果不需要,可在子查询中进一步去重。
方法二:使用窗口函数排序取第一条
利用row_number()窗口函数对每个table1的记录匹配到的table2记录按日期倒序排序,取排序为1的那条(即最近日期):
proc sql; create table table3 as select * from ( select a.*, b.*, row_number() over (partition by a.username, a.id order by b.date desc) as rn from table1 as a left join table2 as b on a.username = b.username and datepart(a.date) >= datepart(b.date) ) as temp where rn = 1; quit;
这种方法会自动为每个a.username+a.id组合保留唯一一条最近日期的table2记录,即使table2中有同日期的多条记录,也只会取其中一条(排序规则由order by决定,若需随机取则保持现有写法,若需特定规则可补充排序字段)。
内容的提问来源于stack exchange,提问作者siddop3
相关产品推荐
相关产品推荐

