SAS EG中如何基于总行数动态筛选跳过最新日期的3个Paid_Date
SAS EG 动态筛选指定Paid_Date记录实现方案
需求梳理
- 从
PaidDateTable表提取格式为YYYYMM的Paid_Date字段 - 跳过时间最新的1条
Paid_Date记录,仅选取时间最近的3个历史月份值 - 逻辑支持动态适配:表内数据随时间更新、总行数变化时,始终自动筛选出最新日期之前的最后3条记录,基于行号+总行数的逻辑实现
测试场景说明
现有测试查询语句:
SELECT "Paid_Date" FROM PaidDateTable WHERE "Paid_Date" > '202201';
语句执行返回结果:
202201 202202 202203 202204 202205
该场景下期望返回结果为:
202202、202203、202204
预期参考筛选逻辑:匹配行号满足RowNumber = TotalRowCount - 1 OR RowNumber = TotalRowCount - 2 OR RowNumber = TotalRowCount - 3的记录
具体实现代码
方法1:PROC SQL 窗口函数实现(完全匹配预期行号逻辑)
SAS的PROC SQL支持窗口函数,可直接在查询内生成行号、计算总行数,无需额外中间步骤,代码如下:
PROC SQL; CREATE TABLE result AS SELECT Paid_Date FROM ( SELECT Paid_Date, /* 按Paid_Date升序生成连续行号,数值越大对应日期越新 */ ROW_NUMBER() OVER (ORDER BY Paid_Date) AS row_num, /* 统计符合前置过滤条件的总记录数 */ COUNT(*) OVER () AS total_count FROM PaidDateTable WHERE Paid_Date > '202201' /* 可替换为实际业务需要的前置过滤条件 */ ) t /* 跳过行号最大的最新1条记录,取往前数3条 */ WHERE row_num BETWEEN total_count - 3 AND total_count - 1 ORDER BY Paid_Date; QUIT;
用测试样例验证:该查询计算得到total_count=5,筛选条件等价于row_num BETWEEN 2 AND 4,返回结果完全匹配预期。数据更新时total_count会自动重算,无需手动修改参数。
方法2:DATA步实现(大数据量下性能更优)
如果表数据量较大,推荐用SAS原生DATA步逻辑实现,读取总观测数时无需全表扫描,执行效率更高:
/* 第一步:按Paid_Date升序排序,保证日期越新排序越靠后 */ PROC SORT DATA=PaidDateTable OUT=sorted_tmp; WHERE Paid_Date > '202201'; /* 替换为实际前置过滤条件 */ BY Paid_Date; RUN; /* 第二步:基于总观测数筛选目标记录 */ DATA result; SET sorted_tmp nobs=total_count; /* _n_为SAS内置变量,对应当前读取的观测序号(即排序后的行号) */ IF _n_ >= total_count - 3 AND _n_ <= total_count - 1; RUN;
两种方法均能实现动态适配:无论表内新增多少月份的数据,都会自动跳过最新月份,返回之前最近的3个历史Paid_Date值。
内容的提问来源于stack exchange,提问作者cole_a
相关产品推荐
相关产品推荐

