【发布时间】: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