使用%if%then%else进行SAS条件连接

时间:2019-09-27 19:06:14

标签: join sas conditional-statements sas-macro

我正在尝试连接两个表,权重1和权重2。 我想先在ID1 = ID2上加入这两个表。 如果缺少ID,我将加入DOB1 = DOB2。 我希望程序比较表中的每一行。 但是sas看到weight2表中缺少第一个ID,然后完全切换到else语句,并使用DOB1 = DOB2进行联接。

我的理想结果是连接四行。但是现在,SAS仅给我三行。

data weight1;    

   input ID1 $ Week1 DOB1; 

   datalines;            
1111 195  101
2222 220  102
3333 173  103
4444 135  104
;                           

proc print data=weight1;    
run; 

data weight2;    
  infile datalines missover;  
   input ID2 $ Week2 DOB2; 

   datalines;            
     195  101
2222 220  102
3333 173  103
4444 135  104
;                           

proc print data=weight2;    
run;  

options mlogic symbolgen mprint; 
%macro test ;
proc sql;
create table final as 
select a.ID1, a.DOB1, b.ID2,b.DOB2

from weight1 a
%if %sysfunc(exist(b.ID2)) %then 
inner join weight2 b 
on a.ID1 = b.ID2;
%else 
/*%if %sysfunc(not exist(b.IDnumber))*/
inner join weight2 b
on a.DOB1 = b.DOB2
;
;
quit;
%mend test;

%test

Sas日志:

LOGIC(TEST):  Beginning execution.
MPRINT(TEST):   proc sql;
MLOGIC(TEST):  %IF condition %sysfunc(exist(b.ID2)) is FALSE
MPRINT(TEST):   create table final as select a.ID1, a.DOB1, b.ID2,b.DOB2 from weight1 a inner join weight2 b on a.DOB1 = b.DOB2 ;
NOTE: Table WORK.FINAL created, with 3 rows and 4 columns.

这是我理想的结果

ID1    DOB1 ID2    DOB2
1111    101         101
2222    102 2222    102
3333    103 3333    103
4444    104 4444    104

2 个答案:

答案 0 :(得分:0)

如果您对DOB上的联接和对ID上的联接的信任程度一样高,则只需执行on a.ID1 = b.ID2 or a.DOB1 = b.DOB2。但是我认为当ID不丢失时,DOB匹配可能会给出一些错误的结果。

您可以先选择具有两组ID的所有行,然后选择DOB匹配且缺少ID的所​​有行。使用union将它们放入同一表。我现在无法测试我的代码,但是像这样:

proc sql;
create table final as 
select a.ID1, a.DOB1, b.ID2,b.DOB2
from weight1(where=(not missing(ID1)) a 
 inner join weight2(where=(not missing(ID2)) b 
 on a.ID1 = b.ID2
union
select a.ID1, a.DOB1, b.ID2,b.DOB2
from weight1 a 
 inner join weight2 b 
 on a.DOB1 = b.DOB2 and (missing(ID1) or missing(ID2))
;

答案 1 :(得分:0)

case表达式可以用作连接条件。

不要使用宏。您使用%sysfunc(exist是错误的,exist函数检查数据集是否存在,并且%sysfunc是在源代码编译之前而不是在SQL执行时执行的。

使用一个case表达式评估相等检查的前提条件。

示例:

data weight1;    

   input ID1 $ Week1 DOB1; 

   datalines;            
1111 195  101
2222 220  102
3333 173  103
4444 135  104
;                           

data weight2;    
  infile datalines missover;  
   input ID2 $ Week2 DOB2; 

   datalines;            
.    195  101
2222 220  102
3333 173  103
4444 135  104
;                           

proc sql;
  create table want as
  select a.ID1, a.DOB1, b.ID2,b.DOB2
  from weight1 a
  join weight2 b
    on case 
         when (a.id1 is not missing and b.id2 is not missing) then a.id1=b.id2
         when (a.dob1 is not missing and b.dob2 is not missing) then a.dob1=b.dob2
         else 0
       end
  ;

注意:如果实际数据的情况是每个表中都有多行缺少ID,并且出生日期相同,则结果表中的行数将成倍增加。例如以下示例数据:

1111 195  101
2222 220  102
3333 173  103
4444 135  104
.    145  105 ***
.    175  105 ***     

.    195  101
2222 220  102
3333 173  103
4444 135  104
.    155  105 ***
.    166  105 ***

4 = 2 x 2来自加星标数据的结果行。