【问题标题】:SAS Hash Table (Right Join/Union)SAS 哈希表(右连接/联合)
【发布时间】:2016-04-30 20:09:02
【问题描述】:

我正在寻找一种在联接和联合之间混合的查找。我的主数据集中有大量记录,所以我想做一些不会是多对多矩阵的“蛮力”方法的事情。

这是我的主要数据集,称为“全部”,其中已经包含列出的每个产品的价格。

product date        price   
apple   1/1/2011    1.05    
apple   1/3/2011    1.02
apple   1/4/2011    1.07

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

我的其他数据集(“价格” - 此处未显示,但包含相同的两个键,产品和日期)包含所有产品在每个可能日期的价格。我想创建的哈希表查找基本上会查找“所有”表中的每个日期,并输出该日期 ALL 产品的价格,从而生成如下表:

product date        price
apple   1/1/2011    1.05    
pepper  1/1/2011    0.71 *
apple   1/2/2011    1.04 *
pepper  1/2/2011    0.73
apple   1/3/2011    1.02
pepper  1/3/2011    0.75
apple   1/4/2011    1.07
pepper  1/4/2011    0.76 *
apple   1/6/2011    1.10 *
pepper  1/6/2011    0.79

也就是说,只要一种产品有一个指定日期和价格的“全部”表,所有其他产品也应该从查找表中提取它。 星号表示价格是从价格表中查找的,包含产品价格的新行基本上被插入到新表中。

如果哈希表不是解决此问题的好方法,请告诉我替代方法。

【问题讨论】:

  • 您想要的 WANT 数据集只是 PRICES 数据集的一个子集吗? (来自 PRICES 的记录,其中 DATE 是 ALL 中的日期之一?)。 ALL 和 PRICES 中有多少条记录?
  • 就本示例而言,是的。实际上,每个密钥实际上都有数千个交易,其中价格列出了不同的产品、日期和价格。这就是为什么我认为哈希在这里是可靠的。
  • 但是,这个想法是每个日期的所有产品都需要价格,只要该日期列出了至少一种产品。
  • 建议您编辑数据,使 ALL 每个键都有一些事务,并添加一个 PRICES 数据集。您愿意接受 SQL 解决方案吗?
  • 当然。我知道蛮力方法是在价格上留下连接,然后通过消除价格中所有日期的过程,这些日期在所有中都不是。我希望有更优雅的东西,但我对方法并不严格。

标签: sas hashtable


【解决方案1】:

这远非优雅,但好奇下面的内容是否能给您想要的结果?由于您在 ALL 中的每个键都有多个记录(我假设您想要维护),所以我基本上将 ALL 与 PRICES 中在 All 中有日期的记录结合起来,但我添加了一个 except 以便排除已经在 ALL 中的记录.不知道这是否有意义,或者正在做你想做的事。当然不能称为“优雅”。

data all;
  input product $7. date mmddyy10. price;
  Y=1;
  format date mmddyy10.;
  cards;
apple  01/01/2011  1.05
apple  01/01/2011  1.05
apple  01/03/2011  1.02
pepper 01/02/2011  0.73
pepper 01/03/2011  0.75
pepper 01/06/2011  0.79
;
run;
data prices;
  input product $7. date mmddyy10. price;
  format date mmddyy10.;
  cards;
apple  01/01/2011  1.05
apple  01/02/2011  1.04
apple  01/03/2011  1.02
apple  01/04/2011  1.07
apple  01/05/2011  1.01
pepper 01/01/2011  0.70
pepper 01/02/2011  0.73
pepper 01/03/2011  0.75
pepper 01/04/2011  0.76
pepper 01/05/2011  0.77
pepper 01/06/2011  0.79
;
run;

proc sql;
  create table want as 
  select * from all 
  union corr all
  ( (select product,date,price from
      prices
      where date IN (select distinct date from all)
    )
    except corr
    select product,date,price from all
  )
  ;
quit;

【讨论】:

  • 谢谢,我觉得这很不错。唯一的事情是......数据集 ALL 有很多我没有列出的字段,我不想删除任何一个。我不太了解 corr/all 关键字,但这里的 corr 关键字似乎指定仅覆盖两个表之间的对应列。 ALL 有大约 30 个字段,PRICES 只有 6 个(我可以删除除 3 个以外的所有字段)。当我运行这个时,无论有没有 corr/all 的某种组合,我仍然得到一个错误......
  • - 警告:已使用空列扩展表以执行 EXCEPT 集操作。错误:EXCEPT 的第一个贡献者的第 6 列与第二个贡献者的类型不同。错误:EXCEPT 的第一个贡献者的第 7 列与第二个贡献者的类型不同。这很容易纠正吗?
  • 我应该补充一点,如果“插入的行”几乎全部为 NULL,我不介意,重要的是填充了产品、价格和日期字段。
  • 我更新了代码以在 ALL, Y 中添加一个额外的变量。我将除了子查询从 select * 更改为选择产品、日期、价格。这应该避免你得到的错误。
  • 好吧,没关系,我发现我可以通过简单地更改列顺序来纠正这个问题。感谢您的建议。
猜你喜欢
  • 2012-09-16
  • 2010-11-29
  • 2019-01-24
  • 2017-07-13
  • 1970-01-01
  • 2016-12-13
  • 2016-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多