SAS:加入两个表并保留行数

时间:2016-04-19 16:01:46

标签: 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      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

table2中有3行id 001,但我只想用table1连接id 001的前2行。我尝试使用inner join,但结果超过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;

希望尽快得到你的答案,提前谢谢!

5 个答案:

答案 0 :(得分:1)

更新:因此,您希望从table2获取table1的第一个观察点,并使用相同的id-product,第二次观察第二次,等等。你需要做的更复杂。

首先,对于每个id-product分组,我们需要假设table2中有> =该记录数,否则合并将导致null referencefusion列的值。

您需要做的是为每个数据表添加一个额外的counter列,然后在该字段上合并。这将用于配对记录。要做到这一点:

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_wCount加入table2_wCount
A.id=B.id and A.product=B.product and A.counter=B.counter

答案 1 :(得分:0)

删除table2中的重复项(PROC SORT NODUPKEY),然后保持连接table1和table2。

答案 2 :(得分:0)

我认为最简单的方法是创建自己的连接参考。在您给出的示例中,可以按如下方式完成:

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”声明无关紧要。

答案 3 :(得分:-1)

尝试使用左连接。我认为它会以这种方式工作。 LEFT JOIN关键字返回左表(table1)中的所有行,右表(table2)中的匹配行。没有匹配时,右侧的结果为NULL。 http://www.w3schools.com/sql/sql_join_left.asp

答案 4 :(得分:-1)

所以完整的答案似乎是先删除table2中的重复条目,然后重新运行代码。如果这不是你要找的结果,你需要更详细地解释这个问题

proc sort nodupkey data = table2 out = table3;     通过id产品;     运行;

proc sql;                                                                                                                               
create table fusion as                                                                                                                  
select                                                                                                                                  
   A.*,                                                                                                                          
   B.date                                                                                                                         
 from table1                      A                                                                                                   
 left  join                                                                                                                           
 table3                           B                                                                                                   

 on A.id=B.id 
 and A.product=B.product;                                                                                                
 quit;