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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:15:58