如何根据时间和重叠数值范围为数据集指定值? - SAS

时间:2015-07-22 22:16:09

标签: sas overlap transpose

我有一个信用卡交易数据集(让我们称之为" Trans"),交易金额为邮政编码日期 。我有另一个数据集(让我们称之为" Key"),根据 date geocode 列出销售税率。 Key数据集还包括与每个地理编码关联的一系列邮政编码,由2个变量表示:Zip Start和Zip End。

由于地理编码与邮政编码不对齐,因此部分邮政编码范围会重叠。如果发生这种情况,我想使用与Trans。

中显示的邮政编码相关的最低销售税率

Trans数据集:

TransAmount TransDate TransZip
$200 01/07/1998 90010
$12 02/09/2002 90022

关键数据集:

Geocode Rate StartDate EndDate ZipStart ZipEnd
1001 .0825 199701 200012 90001 90084
1001 .085 200101 200812 90001 90084
1002 .0825 199701 200012 90022 90024
1002 .08 200101 200812 90022 90024

期望的输出:

TransAmount TransDate TransZip Rate
$200 01/07/1998 90010 .0825
$12 02/09/2002 90022 .08

我在SAS中使用了这个基本的SQL代码,但是我遇到了重叠邮政编码的问题。

 proc sql;
 create table output as
 select a.*, b.zipstart, b.zipend, b.startdate, b.enddate, b.rate
 from Trans.CA_Zip_Cd_Testing a left join Key.CA_rates b
  on a.TranZip ge b.zipstart
  and a.TranZip le b.zipend
  and a.TransDate ge b.StartDate
  and a.transDate le b.EndDate
;
quit;

2 个答案:

答案 0 :(得分:0)

这是最简单的方法,只要查询部分只是添加一个子查询来获得最小速率。

Select t.transamount, t.transdate,t.transzip
        ,(Select MIN(rate) from Key where t.transzip between ZipStart and ZipEnd and t.transdate between startdate and enddate) 'Rate'
from trans t

您也可以将其作为子查询并加入其中。

答案 1 :(得分:0)

SAS SQL Optimizer有时会很好。其他时候,这可能是一个挑战。这段代码会有点复杂,但它可能会更快,并且会受到密钥表的大小限制。

data key;
set key;
   dummy_key=1;
run;

data want(drop=dummy_key geocode rate startDate endDate zipStart zipEnd rc i);
if _n_ = 1 then do;
 if 0 then set key;
 declare hash k (dataset:'key',multidata:'y');
 k.defineKey('dummy_key');
 k.defineData('geocode','rate','startdate','enddate','zipstart','zipend');
 k.defineDone();
end;
call missing (of _all_);
set trans;
dummy_key=1;

rc = k.find();
do i=1 to 1000 while (rc=0);
transZipNum = input(transZip,8.); *converts character zip to number. if its    already a number then remove;
zipStartNum = input(zipStart,8.);
zipEndNum = input(zipEnd,8.);

if startDate <= transDate <= endDate then do;
     if zipStartNum <= transZipNum <= zipEndNum then do;
          rate_out = min(rate_out,rate);
     end;
end;
rc=k.find_next();
end;
run;