小编典典

SAS中的合并工作(IN =)

sql

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

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

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语句的 概念STEP BY STEP的 工作,并证明上述结果。 merge``In=

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

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

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


阅读 336

收藏
2021-03-23

共1个答案

小编典典

基本上,这是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

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

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

left  right
1     1
2     2
3     3
3     4
2021-03-23