在SAS中使用合并(使用IN =)

时间:2015-11-09 15:19:37

标签: sql sas

我有两个dataset data1和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;

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

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

我想知道SAS中merge语句的概念 STEP BY STEP 工作In=并证明了上述结果。

PS:我已阅读this,并说

  

这些变量的一个明显用途是控制什么样的'合并'   将使用if语句发生。例如,如果   ThisRecordIsFromYourData和ThisRecordIsFromOtherData;将成为SAS   仅包含与两个输入数据的by变量匹配的行   集合(如内部联接)。

我猜,(就像内部加入一样)并非总是如此。

1 个答案:

答案 0 :(得分: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

使用BY值在每一侧(或两者)产生每个值的唯一记录,它实际上与SQL相同。但是,使用在两个边上产生重复的BY值,您可以得到您所拥有的内容:并排合并,如果一个在另一个之前耗尽,则从较短数据集的最后一行开始的值(对于价值)或多或少被复制下来。 (它们实际上是保留的,因此如果您使用更改覆盖它们,它们将不会重置来自较长数据集的新记录。)

因此,如果left有3条记录且right有4条关键值a的记录,就像您的示例一样,那么您可以从以下记录中获取数据(假设您没有&# 39; t之后改变数据:

left  right
1     1
2     2
3     3
3     4