Tartaglia的答案相當接近,但它可能更容易一步完成。
data x1 x2;
merge x(in=x) a(in=found keep=id) b(in=found keep=id) c(in=found keep=id);
by id;
if x and found then output x1;
else if x then output x2;
run;
確保「發現」和「X」是任何原始數據集不變量,否則使用別的 唯一複雜的因素是,如果你想從A,B,C比ID其他一些變量;如果你這樣做,那麼你需要弄清楚如何確保你得到正確的變量,如果你有一個多重匹配場景。還需要整理所有四個表格(可能會很慢)。
另一個SAS解決方案:散列表。這是而不是需要排序你的數據集。如果您的數據集尚未排序,這可能會更快。但是,它確實需要足夠的內存來將所有表a,b和c存儲在內存中,這可能會受到這些數據集大小的限制;當a,b,c相對於x較小時,而不是當它們的尺寸相似時更好。可以使用defineData來操縱這些數據,以便從a/b/c中生成數據,而不僅僅是返回代碼,但是如果在a,b,c中的兩個中找到想要執行的操作,三個全部)。
data abc/view=abc;
set a b c;
keep id;
run;
data x1 x2;
if _n_ = 1 then do;
declare hash abc(dataset:"abc");
abc.defineKey("id");
abc.defineDone();
call missing(id);
end;
set x;
rc = abc.find();
if rc=0 then output x1;
else output x2;
run;
要做到這一點在Oracle中,我想我會做的是做一些更接近塔爾塔利亞的解決方案的方式 - 創建三個「匹配」的表,然後工會它們(除去在工會重複),然後創建x2作爲x減x1表。
create table x1 as
select x.* from x,a where x.id=a.id
union
select x.* from x,b where x.id=b.id
union
select x.* from x,c where x.id=c.id
;
create table x2 as
select * from x except select * from x1;
我測試過這些了使用SAS(包括SQL解決方案,Oracle可能會好一點的,但是:IE瀏覽器(Oracle是否準確以外,則這個作品在PROC SQL在SAS,不知道)應該是類似的順序 - 但如果你的oracle服務器比你的sas服務器更快,那可能會改變一些東西)。
使用數據集'x'與5e7記錄和三個數據集'a''b''c'進行公平重疊(大概25%左右的記錄在2個或更多數據集中,84%在一個或更多)和每個1.5e7和3e7記錄之間(具體來說,其中一個具有所有奇數,一個具有3的倍數,並且一個具有4的倍數),SQL解決方案花費了5分鐘來處理,而排序合併解決方案需要大約2.5分鐘的時間進行排序,0.5分鐘的時間進行合併,因此大約需要3分鐘。這可能會稍微誇張,因爲數據集是按照順序創建的,所以排序本身的速度可能會稍微快一些(儘管SQL也會從數據集中獲得一些)。
這與5e7數據集x的寫出時間約5秒相比較。
哈希解決方案將不適合我的筆記本電腦與整體〜6e7記錄數據集abc,所以我把它們縮小到總共〜2e7(所以賠率從1到2e7,然後3的倍數從2e7到4e7,然後是從4e7到6e7的4的倍數),但是剩下x有5e7條記錄。與排序和合並解決方案相比,散列解決方案總共花費了1·41分鐘,而排序和合並解決方案花費了相似的時間,其中大部分是排序x(大約一分鐘)併合並/寫出結果數據集(大約半分鐘) 。這比排序較大的數據集要快得多,因爲較小的數據集在內存中排序,而較大的數據集則不能。這些數據集的SQL解決方案大約需要4分鐘,所以仍然相當慢。
來源
2012-12-27 14:36:01
Joe
「非常大」有多大? – sasfrog
我們可以安全地假設所有表的行數> 50 M。 –
...多少列?此外,這是你打算做很多次,或一次性的東西?一旦你找到了匹配,你會重新創建X1和X2,還是添加到它們?或者在你檢查完X後,X中的行會再次變化嗎? – sasfrog