我有两个dataset
数据1和数据2
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
我想知道concept and 一步步的工作merge
SAS 中的语句In=
并证明上述结果。
PS:我读过this,它说
这些变量的一个明显用途是控制“合并”的类型
使用 if 语句将会发生。例如,如果
此记录来自您的数据和此记录来自其他数据;将使SAS
仅包含与两个输入数据中的 by 变量匹配的行
集(如内连接)。
我想,(就像内部联接)并不总是如此。
基本上,这是由于 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 值在两侧都产生重复项,您将得到那里的结果:并排合并,如果一个在另一个之前用完,则来自较短数据集最后一行的值(对于该数据集)值)或多或少被复制下来。 (它们实际上是保留的,因此如果您用更改覆盖它们,它们不会在较长数据集中的新记录上重置)。
So, if left
有 3 条记录并且right
键值有4条记录a
,就像在您的示例中一样,然后您从以下记录中获取数据(假设您之后不更改数据):
left right
1 1
2 2
3 3
3 4
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)