SAS中的合并工作(IN =)

rhi*_*itz 2 sql sas

我有两个datasetdata1和data2

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;
Run Code Online (Sandbox Code Playgroud)

我从下面的代码合并它们:

data join;
merge data1(in=a) data2(in=b);
by id;
if a and b;
run;
Run Code Online (Sandbox Code Playgroud)

结果:(我期待的不是内部联接结果)

1   a   10  x
2   a   20  y
2   a   30  z
2   a   40  w
Run Code Online (Sandbox Code Playgroud)

proc sql内部联接的结果。

proc sql;
select data1.id,sn,sales,x from data2 inner join data1 on data1.hh_id;
quit;
Run Code Online (Sandbox Code Playgroud)

结果:(如内部联接所预期的那样)

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
Run Code Online (Sandbox Code Playgroud)

我想知道SAS语句的概念STEP BY STEP的工作,并证明上述结果。 mergeIn=

PS:我已经读过,上面写着

这些变量的一个明显用途是使用if语句来控制将发生哪种“合并”。例如,如果ThisRecordIsFromYourData和ThisRecordIsFromOtherData; 将使SAS仅包括与两个输入数据集中的by变量匹配的行(例如内部联接)。

我猜(就像内部联接)并非总是如此。

Joe*_*Joe 5

基本上,这是SAS数据步骤和SQL处理它们各自的联接/合并方式不同的结果。

SQL为每种可能的键组合创建单独的记录。这是笛卡尔乘积(在关键级别)。

但是,SAS数据步骤的合并过程非常不同。 MERGE实际上只是特殊情况而已SET。它仍然迭代地处理行,一次一次-它永远不会返回,并且一次PDV中的任何数据集都不会超过一行。因此,它无法在其正常过程中创建笛卡尔乘积-这将需要随机访问,而SAS数据步骤通常无法进行这种访问。

它能做什么:

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
Run Code Online (Sandbox Code Playgroud)

使用BY值可在任一侧(或同时在两侧)每个值生成唯一记录,它实际上与SQL相同。但是,如果BY值在两边都产生重复,那么您将得到:并排合并,如果一个在另一个之前用完,则来自较短数据​​集的最后一行的值(对于值)大致复制下来。(它们实际上是保留的,因此,如果您用更改覆盖它们,它们将不会在较长数据集中的新记录上重置)。

因此,如果left有3条记录,并且right有4条键值记录a,例如在您的示例中,那么您将从以下记录中获取数据(假设您之后没有更改数据):

left  right
1     1
2     2
3     3
3     4
Run Code Online (Sandbox Code Playgroud)