【问题标题】:SAS Recursive JoinSAS 递归连接
【发布时间】:2015-09-24 23:20:01
【问题描述】:

我有一个大的连接表,并希望扩展该表以包含递归连接。

我的数据看起来像这样--

data city_list;  

input from_city $ to_city $;
datalines;  
PORTLAND SEATTLE
SEATTLE BOISE
BOISE PORTLAND
PORTLAND HELENA
NYC ORLANDO
ORLANDO MIAMI
;
run;

我想扩展数据集以包括中途停留,所以它最终看起来像这样。我不关心我是否同时拥有“PORTLAND/SEATTLE”和“SEATTLE/PORTLAND”记录——之后我可以根据需要处理这些记录。

BOISE   HELENA
BOISE   PORTLAND
BOISE   SEATTLE
NYC MIAMI
NYC ORLANDO
ORLANDO MIAMI
PORTLAND    HELENA
PORTLAND    SEATTLE
SEATTLE HELENA

我尝试使用以下宏,但是当递归级别过多时遇到了性能问题。我相信最好的选择是哈希表,但我不确定如何编写这种精确的场景。

data city_list;  

input from_city $ to_city $;
datalines;  
PORTLAND SEATTLE
SEATTLE BOISE
BOISE PORTLAND
PORTLAND HELENA
NYC ORLANDO
ORLANDO MIAMI
;
run;

%macro RecurJoin(
baseTbl,
destTbl,
baseKey,
compKey
);

Proc SQL;
Create Table WORK.RECUR_JOIN_TBL as
SELECT distinct Base.&baseKey, Connect.&compkey
  FROM &baseTbl AS Base
       INNER JOIN &baseTbl AS Connect
          ON (Base.&compkey = Connect.&baseKey)
       LEFT JOIN &baseTbl AS Subbase
          ON (Base.&baseKey = Subbase.&baseKey) AND
             (Connect.&compkey = Subbase.&compkey)
 WHERE Subbase.&baseKey IS NULL;
quit;

  proc sql noprint;
    select count(1) into :connectCnt from RECUR_JOIN_TBL;
  quit;

Data &destTbl;
  set &baseTbl
      RECUR_JOIN_TBL;
run;

    Proc DataSets nolist;
        Delete RECUR_JOIN_TBL;
    Quit;

%if &connectCnt > 0 %then %do;
    %RecurJoin(
    baseTbl=&destTbl,
    destTbl=&destTbl,
    baseKey=&baseKey,
    compKey=&compKey
    );
%end;

%mend;

%RecurJoin(
baseTbl=city_list,
destTbl=FNL_CITY_LIST,
baseKey=from_city,
compKey=to_city
);

Proc Sort data=WORK.FNL_CITY_LIST (where=(NOT(from_city=to_city)));
  by from_city to_city;
run;

【问题讨论】:

  • 解决此类问题的最佳数据结构(假设没有无限递归)是扁平树结构。根据您查询数据集的频率以及您的性能要求,这可能是矫枉过正。这里有一些很好的例子来开始。如果明天我有时间,我会想出一个正确的答案,但也许你也会打败我=)示例 1)sitepoint.com/hierarchical-data-database-2 和示例 2)ibase.ru/devinfo/DBMSTrees/sqltrees.html
  • 感谢您的链接!您有关于 SAS 上下文的任何信息吗?
  • 我正在整理一些东西,但可能还要几天,因为我现在很忙。

标签: sas


【解决方案1】:

如果内存允许,您可以使用我在this answer 中提出的基于哈希的方法来识别数据集中连接的城市组。然后,您只需为同一组中的每一对城市生成一行,这可以通过proc sql 中的笛卡尔连接轻松完成。

【讨论】:

  • 我用以下数据集尝试了这段代码,但它没有按预期工作——它将所有这些 id 分组到一个集合中,而不是两个集合。你有什么想法我可以解决这个问题吗?我用以下数据集尝试了这段代码,但它没有按预期工作——它将所有这些 id 分组到一个集合中,而不是两个集合。数据有;输入id1 id2;牌; 345488 356536 345488 357799 351491 351598 351491 351600 351598 351600 356536 357799;运行;
  • @Netbrian 我想我已经发现了问题的原因,并且我已经更新了该答案中的代码,但我现在无法测试它。请有机会再看看,看看它是否按预期工作。
  • 这似乎奏效了!在结束问题之前,我将在今天晚些时候进行更多试验,但情况看起来很积极。非常感谢!
  • 我现在也对其进行了测试,我倾向于同意。如果您发现任何其他错误行为,请告诉我。
猜你喜欢
  • 1970-01-01
  • 2013-07-31
  • 2017-05-28
  • 2014-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-05
相关资源
最近更新 更多