通过2个数据集进行SAS循环/查找

时间:2016-05-01 17:15:56

标签: sas hashtable lookup

我有2个数据集,一个大,一个小。虽然功能在这里最重要,但效率也很重要,因为大数据集可能有数千万条记录。让我们调用我的大型数据集" Transactions"和我的小人物#34;价格。"这就是我想要做的事情。在交易文件中,有一堆值为' Store'。对于每个商店,我想创建一个相关产品的哈希表,并为每个唯一的产品'提取所有产品'价格'进入输出表,而不是只是的相关产品'但对于所有'产品'在事务数据集找到,用于该商店'

这是" Transactions"的一个示例。数据集:

Store   Product SaleDate  Price
A       apple   1/1/2011  1.05
A       apple   1/3/2011  1.02
A       apple   1/4/2011  1.07

A       pepper  1/2/2011  0.73
A       pepper  1/3/2011  0.75
A       pepper  1/6/2011  0.79

这是"价格"的样本。数据集:

        Product Saledate    Price
        apple   1/1/2011    1.05  
        apple   1/2/2011    1.06
        apple   1/3/2011    1.02
        apple   1/4/2011    1.07
        ...

        pepper  1/1/2011    0.74
        pepper  1/2/2011    0.73
        pepper  1/3/2011    0.75
        pepper  1/4/2011    0.75
        pepper  1/5/2011    0.75    
        pepper  1/6/2011    0.79
        ...

        mango   1/1/2011    2.40
        mango   1/2/2011    2.42
        ...

这里是这个场景的理想输出(星号表示价格从"价格"插入"交易"通过查询)。

 Store  Product Saledate    Price
 A      apple   1/1/2011    1.05    
 A      pepper  1/1/2011    0.74 *
 A      apple   1/2/2011    1.06 *
 A      pepper  1/2/2011    0.73
 A      apple   1/3/2011    1.02
 A      pepper  1/3/2011    0.75
 A      apple   1/4/2011    1.07
 A      pepper  1/4/2011    0.75 *
 A      apple   1/6/2011    1.10 *
 A      pepper  1/6/2011    0.79

基本上,在伪代码中,想法是循环遍历每个商店,查找其不同产品和saledates的列表,然后在价格数据中找到这些产品和saledate的相应价格,如果它们不是,则插入它们已经在那了。在这个例子中,由于苹果有一个1/1的交易量"交易",我也需要辣椒的saledate(来自"价格")。这同样适用于1/2,反之亦然,因为辣椒的价格已经存在,但不适用于苹果。 1/5在"价格"中有记录,但它不需要,因为在交易中没有苹果/胡椒发生。""对于另一家商店,存在不同的产品,因此胡椒根本不相关,但是芒果是。

我已经尝试了几种方法,无法绕过" double"我认为有必要查找挂断。

以下是与此新问题相关的上一个问题/答案的链接。答案提供了创建虚拟表的示例代码。 https://stackoverflow.com/a/36961795/214994

1 个答案:

答案 0 :(得分:1)

我认为你可以用一系列SQL语句来完成你想要的东西。

data trans;
format Store $1. Product $6. SaleDate mmddyy10. price best.;
informat SaleDate mmddyy10.;
input Store $ Product $ SaleDate price;
datalines;
A       apple   1/1/2011  1.05
A       apple   1/3/2011  1.02
A       apple   1/4/2011  1.07
A       pepper  1/2/2011  0.73
A       pepper  1/3/2011  0.75
A       pepper  1/6/2011  0.79
B       apple   1/1/2011  1.05
B       apple   1/3/2011  1.02
B       apple   1/4/2011  1.07
B       mango  1/2/2011  2.42
B       mango  1/3/2011  2.43
B       mango  1/6/2011  2.46
;

data prices;
format Product $6. SaleDate mmddyy10. price best.;
informat SaleDate mmddyy10.;
input Product $ SaleDate price;
datalines;
apple   1/1/2011    1.05
apple   1/2/2011    1.06
apple   1/3/2011    1.02
apple   1/4/2011    1.07
apple   1/5/2011    1.10
apple   1/6/2011    1.15
pepper  1/1/2011    0.74
pepper  1/2/2011    0.73
pepper  1/3/2011    0.75
pepper  1/4/2011    0.75
pepper  1/5/2011    0.75
pepper  1/6/2011    0.79
mango   1/1/2011    2.40
mango   1/2/2011    2.42
mango   1/3/2011    2.43
mango   1/4/2011    2.44
mango   1/5/2011    2.45
mango   1/6/2011    2.46
;

proc sql noprint;
/*Store and Date Combinations*/
create table store_dates as
select distinct store, saledate
    from trans;

/*Store and Product Combinations*/
create table store_products as
select distinct store, product
    from trans;

/*Full Joins the combination tables and look up the price with a left join*/
create table want as
select a.store,
       b.product,
       a.saledate,
       c.price
    from store_dates as a
      full join
         store_products as b
        on a.store=b.store
      left join
         prices as c
      on b.product = c.product
     and a.saledate = c.saledate
    order by a.store, a.saledate, b.product;
quit;

这假设TRANS和PRICES之间的价格没有差异。如果是这样,添加TRANS的另一个左连接和coalesce()来处理。