2012-12-27 43 views
1

我有4個非常大的表。讓我給他們打電話X,A,B和C來自多個表/數據集的Oracle/SAS記錄匹配

我想創建從X兩個表X1和X2如下:

考慮表X的記錄r如果R有相應的記錄至少有一個表A,B和C,我把它放在X1中。否則我把它放在X2中。

(我如何確定r在A,B或C中有相應的記錄?我將r的幾個字段與A,B或C中的某些記錄的幾個字段進行比較。字段可能與A ,B或C,並且可能有多個條件將r與A,B或C中的記錄進行匹配。可能這個部分與主要問題沒有關係。)

我有兩個選項:I can將X,A,B和C作爲Oracle表或SAS數據集。

解決此問題的最有效方法是什麼?

問候,

+0

「非常大」有多大? – sasfrog

+0

我們可以安全地假設所有表的行數> 50 M。 –

+0

...多少列?此外,這是你打算做很多次,或一次性的東西?一旦你找到了匹配,你會重新創建X1和X2,還是添加到它們?或者在你檢查完X後,X中的行會再次變化嗎? – sasfrog

回答

1

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分鐘,所以仍然相當慢。

0

如果我理解正確的話,你可以做這樣的事情:

合併數據集X和A上要找到匹配的變量從X 輸出記錄匹配的是將表格A記錄到X1中,並將不匹配 的記錄輸出到X2中。

比方說,你正在處理的示例數據集的X和A:

data x; 
input id some_value $; 
datalines; 
1 a 
2 b 
3 c 
4 d 
5 e 
run; 

data a; 
input id some_value $ some_value_2 $; 
datalines; 
1 a x 
4 d v 
5 g u 
run; 

現在,你可以做一個合併這樣的:

data x1_a x2_a; 
merge x(in=table_x) a(in=table_a keep=id some_value); 
by id some_value; 
if table_x = 1 and table_a = 1 then output x1_a; 
if table_x = 1 and table_a = 0 then output x2_a; 
run; 

重複的數據集B和C,改變bykeep聲明如果有 與數據集B和C匹配的不同規則。同時將x1_ax2_a的名稱更改爲x1_b等,因此它們不會得到覆蓋。

追加所有x1_表,並且您有問題中描述的X1數據集(您可能需要處理重複項)。

追加所有x2_表,並計算不同的行。行的數量與 的次數完全相同,您正在比較的初始數據集(在這種情況下爲3,A,B,C)是您保留的數據集。

相關問題