2015-11-09 77 views
1

我有兩個dataset數據1和數據2在SAS合併的工作(與IN =)

data data1; 
input sn id $; 
datalines; 
1 a 
2 a 
3 a 
; 
run; 

data data2; 
input id $ sales x $; 
datalines; 
a 10 x 
a 20 y 
a 30 z 
a 40 q 
; 
run; 

我從下面的代碼將它們合併:

data join; 
merge data1(in=a) data2(in=b); 
by id; 
if a and b; 
run; 

結果:(我期待一個內加入的結果並非如此)

1 a 10 x 
2 a 20 y 
2 a 30 z 
2 a 40 w 

結果來自proc sql內部連接。

proc sql; 
select data1.id,sn,sales,x from data2 inner join data1 on data1.hh_id; 
quit; 

結果:(從內有望加入)

a 1 10 x 
a 1 20 y 
a 1 30 z 
a 1 40 w 
a 2 10 x 
a 2 20 y 
a 2 30 z 
a 2 40 w 
b 3 10 x 
b 3 20 y 
b 3 30 z 
b 3 40 w 

我想知道概念STEP BY在SAS STEP工作的merge語句In=和上述證明結果。

PS:我已閱讀this,和它說

一個明顯的使用了這些變量是控制 會發生什麼樣的「合併」,用if語句。例如,如果 ThisRecordIsFromYourData和ThisRecordIsFromOtherData;將使SAS 僅包含與來自兩個輸入數據 集(如內連接)的變量相匹配的行。

我猜,(像一個Inner Join)並非總是如此。

+1

我相信這是導致問題而非IN或其他任何問題的多對多連接。 – Reeza

回答

4

基本上,這是SAS數據步驟和SQL處理各自加入/合併方式的區別的結果。

SQL爲每個可能的鍵組合創建單獨的記錄。這是一個笛卡兒積(在關鍵層面)。

SAS數據步驟,但是,過程合併非常不同。 MERGE實際上只不過是SET的特例。它仍然以迭代方式處理行,每次只處理一行 - 它永遠不會返回,並且一次不會從PDV中的任何數據集中出現多於一行。因此,它不能在其正常流程中創建笛卡爾產品 - 這將需要隨機訪問,SAS datastep通常不會這樣做。

做些什麼:

For each unique BY value 
    Take the next record from the left side dataset, if one exists with that BY value 
    Take the next record from the right side dataset, if one exists with that BY value 
    Output a row 
Continue until both datasets are exhausted for that BY value 

與可帶來任何一方(或雙方),每個值唯一記錄的值,它是有效地等同於SQL。然而,如果BY值在BOTH方面產生重複,則可以得到您在那裏的結果:並行合併,如果在另一個合併之前耗盡,則較短數據集的最後一行的值(對於該值值)或多或少被複制下來。 (它們實際上是保留的,所以如果用改變覆蓋它們,它們將不會重置來自較長數據集的新記錄)。

所以,如果left有3條記錄和right有4個記錄鍵值a,就像在你的榜樣,那麼您從以下記錄獲取數據(假設你沒有改變後的數據):

left right 
1  1 
2  2 
3  3 
3  4 
+0

謝謝喬,這是精彩的解釋。 –

+1

這是我讀過的這個概念的第一個很好的解釋。做得很好。 –