Sql SAS:联接两个表并保留行数
我想通过变量Sql SAS:联接两个表并保留行数,sql,join,sas,Sql,Join,Sas,我想通过变量id连接两个表,但在我的第一个表中,有一些相同的行,而且这两个表中每个id的行数也不相同。比如说, 表1: id product 001 24 001 24 001 03 002 61 表2: id product date reference 001 24 01jun2015 1 001 24 0
id
连接两个表,但在我的第一个表中,有一些相同的行,而且这两个表中每个id
的行数也不相同。比如说,
表1:
id product
001 24
001 24
001 03
002 61
表2:
id product date reference
001 24 01jun2015 1
001 24 01jun2015 2
001 24 01jun2015 3
001 03 05jun2015 4
002 61 06jun2015 5
现在,我想通过保持table1的行数来连接这两个表,并得到下表:
id product date reference
001 24 01jun2015 1
001 24 01jun2015 2
001 03 05jun2015 4
002 61 06jun2015 5
表2中有3行ID001,但我只想将ID001的前2行与表1连接起来。我尝试使用内部联接
,但结果超过4行。
这是我的密码:
proc sql;
create table fusion as
select
A.*,
B.date,
B.reference
from table1 A
inner join
table2 B
on A.id=B.id and A.product=B.product;
quit;
希望尽快得到您的答案,提前谢谢 更新:因此,我们的想法是,对于
表1
中的第一个观察,使用相同的id产品
,从表2
中提取第一个观察,第二个观察,等等。您需要在这里做的事情更复杂
首先,对于每个id产品
分组,我们需要假设在表2中有>=该数量的记录,否则合并将导致融合
中的引用
列为空值
您需要做的是在每个数据表中添加一个额外的计数器
列,然后在该字段上合并。这将有助于记录的配对。为此:
proc sort data=table1; by id product; run;
proc sort data=table2; by id product; run;
data table1_wCount;
retain counter;
set table1;
by id product;
if first.product THEN counter=0;
counter = counter+1;
end;
data table2_wCount;
retain counter;
set table2;
by id product;
if first.product THEN counter=0;
counter = counter+1;
end;
现在,左键连接table1\u wCount
和table2\u wCount
打开
A.id=B.id and A.product=B.product and A.counter=B.counter
用左连接试试。我想这样行。
LEFT JOIN关键字返回左表(表1)中的所有行,右表(表2)中有匹配的行。当没有匹配项时,右侧的结果为空。
所以完整的答案看起来像是先删除表2中的重复条目,然后重新运行代码。如果这不是你想要的结果,你需要更详细地解释这个问题
proc sort nodupkey data=table2 out=table3;
副产品;
运行
删除表2中的重复项(PROC SORT NODUPKEY),然后留下连接表1和表2。我认为最简单的方法是创建自己的连接引用。在您给出的示例中,可以按如下方式进行:
data table1;
set table1;
by id product notsorted;
if first.product then joinref = 0;
joinref+1;
run;
data table2 (index=(myjoin=(id product joinref)));
set table2;
by id product notsorted;
if first.product then joinref = 0;
joinref+1;
run;
请注意,我假设您的数据已经按照您想要的特定顺序排列,因此我在by语句中使用了notsorted选项。但是,您可能希望按id和产品对数据进行索引或排序,在这种情况下,您可以删除“未排序”选项
我还向第二个表添加了一个复合索引,以便您可以对id、product和新创建的joinref进行键联接。要使用此功能,请执行以下操作:
data table3 (drop = joinref);
set table1;
set table2 key = myjoin / unique;
if _iorc_ ne 0 then do;
_ERROR_ = 0;
date = '';
reference = .;
end;
run;
如果您不熟悉键联接,那么它们将非常高效,并且是一种非常简洁的方法,可以按照特定顺序保存第一个表,同时根据该表中的索引匹配另一个表中的数据。iorc是此匹配的返回码,当找到匹配时,返回码将为0。如果没有匹配项,则应重置查找表中出现的任何新字段,因为存在对拉过的数据的隐式保留-即,如果未找到匹配项,SAS将保留在上一次成功匹配中找到的值,除非将这些字段设置为null(这显然不包括索引字段,因为它们已经存在于您的数据中,并且您正在查找这些字段-在上面的示例中-id、product和joinref)
如果您知道您将始终有一个匹配“如果iorc ne 0”语句是不相关的。它将为id=001和product=24生成相同的结果-3x2=6条记录,而不是删除重复项。我认为您可以使用select distinct of table 2。如果您解释所需连接背后的逻辑,这将有所帮助。表2中同一条记录多次出现是否会对结果产生某种影响?这些重复项是否存在表2中的ed记录始终具有相同的日期
?如果为“否”和“是”然后按照@dashnik的建议消除表2的重复。谢谢你的建议。我在表2中添加了一个新变量reference
,更新了问题,因此表2中没有完全相同的行。好的,但是从加入过程的角度来看,行1-3仍然是重复的。你不使用reference
字段f或者这项任务中的任何内容,对吗?那么,请再次删除重复项或使用@KwstasMost comment中的distinct
。感谢您的回答。似乎我没有很好地解释问题。实际上,表2中没有重复行。您可以检查我问题的更新。不加入表2中第三行的逻辑是什么?
data table3 (drop = joinref);
set table1;
set table2 key = myjoin / unique;
if _iorc_ ne 0 then do;
_ERROR_ = 0;
date = '';
reference = .;
end;
run;