Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql SAS:联接两个表并保留行数_Sql_Join_Sas - Fatal编程技术网

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;