合并vs Proc sql

时间:2017-08-17 19:28:31

标签: merge sas proc-sql

我有两种方法可以做同样的事情但是没有得到相同的结果。这是什么原因?

第一种方式:

Proc sql;
    Create table abc.immu as
    select ID, DATE, CODE
    from xyz.imm
    where DATE between to_date('2008-01-01','YYYY-MM-DD') and to_date('2016-01-31','YYYY-MM-DD')
    Order by CODE);
        Quit;

Proc sql ;
    Create table abc.testb as
             select CODE, description from xyz.REF_code where lower(description)like '%hep b%';
 Quit;

proc sort data=abc.testb;
by code;
run;


data abc.testb1;
merge abc.immu(in=a) abc.testb (in=b);
by code;
if a=1 and b=1;
run;

第二种方式

Create table abc.testb1 as
        Select ID, DATE,CODE
    From xyz.imm
    where CODE in (select CODE from xyz.REF_code where lower(description)like '%hep b%')
    AND  DATE between to_date('2008-01-01','YYYY-MM-DD') and to_date('2016-01-31','YYYY-MM-DD')
    Order by ID, DATE;
    Quit;

proc sort data=abc.testb1 nodupkey;
by ID DATE;
run;

为什么没有得到相同的结果?是不是两种不同的方式来实现同样的目标?

1 个答案:

答案 0 :(得分:0)

最好的猜测是,您在第一个区块的CODE中有重复的abc.testb条记录。 abc.immu表包含该代码,但对于1个或多个testb值的记录少于CODE

举个例子:

测试数据:

data test;
do cd='a','b','c';
    do i=1 to 10;
        output;
    end;
end;
run;

data cds;
do cd='a','c';
    desc=1;
    output;
    desc=2;
    output;
end;
run;

当我们为test中的每个代码提供更多记录时,两者都可以按预期工作。下面会生成相同的记录。

proc sql noprint;
create table sql as
select * from test
    where cd in (select cd from cds);
quit;

data dataStep;
merge test(in=a) cds(in=b);
by cd;
if a and b;
run;

但是,如果我们在cd="a"中将test组剥离为仅1,我们就会遇到问题:

data test2;
set test;
if cd='a' then
    if i=1;
run;

proc sql noprint;
create table sql2 as
select * from test2
    where cd in (select cd from cds);
quit;

data dataStep2;
merge test2(in=a) cds(in=b);
by cd;
if a and b;
run;

现在dataStep2中有一条额外的记录。

要解决此问题,您可以选择以下几种方法:

  1. 从选择中移除description列,然后使用DISTINCT关键字。然后,testb每个CODE只有一行。
  2. 使用SQL解决方案。