如何获取标记值周围的行?

时间:2018-06-25 18:53:42

标签: sql sas

我从这样一个表开始:

code     new_code_flag
abc123   0
xyz456   0
wer098   1
jio234   0
bcx190   0
eiw157   0
nzi123   0
epj676   0
ere654   0
yru493   1
ale674   0

我想在“ new_code_flag” = 1的每个值之前获取2条记录,之后获取2条记录。我希望我的输出看起来像这样:

code     new_code_flag
abc123   0
xyz456   0
wer098   1
jio234   0
bcx190   0
epj676   0
ere654   0
yru493   1
ale674   0

有关如何在SQL或SAS中执行此操作的任何帮助?

3 个答案:

答案 0 :(得分:0)

SQL表表示无序集。因此,在SQL中,您需要具有指定顺序的列。假设您这样做,可以执行以下操作:

with t as (
      select t.*, row_number() over (order by ?) as seqnum
      from tbl t
     )
select t.*
from t
where exists (select 1
              from t t2
              where t2.new_code_flag = 1 and
                    t.seqnum between t2.seqnum - 2 and t2.seqnum + 2
             );

答案 1 :(得分:0)

您可以为flag变量创建两个滞后副本和两个前导副本,然后测试5个变量中的任何一个是否为1(真)。

data have;
  input code $ flag ;
cards;
abc123   0
xyz456   0
wer098   1
jio234   0
bcx190   0
eiw157   0
nzi123   0
epj676   0
ere654   0
yru493   1
ale674   0
;

data want ;
  set have ;
  set have(keep=flag rename=(flag=lead1_flag) firstobs=2) have(drop=_all_ obs=1);
  set have(keep=flag rename=(flag=lead2_flag) firstobs=3) have(drop=_all_ obs=2);
  lag1_flag=lag1(flag);
  lag2_flag=lag2(flag);
  if lag1_flag or lag2_flag or flag or lead1_flag or lead2_flag ;
run;

结果

                         lead1_    lead2_    lag1_    lag2_
Obs     code     flag     flag      flag      flag     flag

 1     abc123      0        0         1        .        .
 2     xyz456      0        1         0        0        .
 3     wer098      1        0         0        0        0
 4     jio234      0        0         0        1        0
 5     bcx190      0        0         0        0        1
 6     epj676      0        0         1        0        0
 7     ere654      0        1         0        0        0
 8     yru493      1        0         .        0        0
 9     ale674      0        .         .        1        0

答案 2 :(得分:0)

data want(drop=_: i);
   merge have have(keep=flag firstobs=3 rename=(flag=_flag));
   if flag or _flag then i=1;
   if 0<i<=3 then do;
      output;
      i+1;
   end;
   else delete;
run;