匹配 table 中不同变量的最后一个值

Match last values of different variables from a table

我有一个 table 存储不同日期的 A 和 B 的值。它看起来像这样:

Date   Amount   Type
2015    15        A 
2014    -3        B 
2013     8        B 
2013    10        A 
2012     5        A 

如何最有效地准备一个table,列出每个日期的当前 A 值和当前 B 值?这个想法是,对于每个日期,直接指定一个值,但另一个值需要是前一个值。

Date   A   B
2015  15  -3
2014  10  -3
2013  10   8

等等

数据集将是一个庞大的数据集(数百万条记录),非常感谢您的帮助。该解决方案将在 SAS 中实施,因此我将使用 SAS 过程或 proc sql 过程(它在自连接方面有其局限性)。

基本上,您想为每个案例重新加入 table。

我不清楚你决定是使用当前还是以前的A金额或B金额的逻辑是什么,但你应该可以在下面的声明中填写它。

select distinct <br>
    dates.[date]<br>
    , CASE WHEN {condition for A} THEN currentA.amount ELSE prevA.amount END as A<br>
    , CASE WHEN {condition for B} THEN currentB.amount ELSE prevB.amount END as B<br>
from myTable dates<br>
LEFT OUTER JOIN myTable currentA on dates.[date] = currentA.[date] and currentA.[type] = 'A'<br>
LEFT OUTER JOIN myTable currentB on dates.[date] = currentB.[date] and currentB.[type] = 'B'<br>
LEFT OUTER JOIN myTable prevA on dates.[date]-1 = prevA.[date] and prevA.[type] = 'A'<br>
LEFT OUTER JOIN myTable prevB on dates.[date]-1 = prevB.[date] and prevB.[type] = 'B'<br>
order by dates.[date] desc<br>

为了获得更好的性能,您可以将日期分组到临时 table 并将其用于开始 table 而不是使用 distinct 关键字。我在这里没有这样做是为了使查询简短。

data have;
input Date   Amount   Type $;
cards;
2015    15        A 
2014    -3        B 
2013     8        B 
2013    10        A 
2012     5        A 
;
data want(keep=date A B);
   merge have have(firstobs=2 rename=(date=_date amount=_amount type=_type));
   retain flag;
   if date-_date=1 then do;
      if flag=1 then do;
           call missing(flag);
           return;
      end;
      if type='A' then do;
         A=amount;
         B=_amount;
      end;
      else if type='B' then do;
         B=amount;
         A=_amount;
      end;
      output;
   end;
   else if date=_date then do;
      flag=1;
      if type='A' then do;
         A=amount;
         B=_amount;
      end;
      else if type='B' then do;
         B=amount;
         A=_amount;
      end;
      output;
   end;
   else if missing(_date) then do;
      if flag=1 then return;
      if type='A' then A=amount;
      else B=amount;
      output;
   end;
run;

正如 Gordon 在评论中所说,我会使用数据步骤和 RETAIN 语句

首先,创建数据集。

其次,按日期升序排列

第三,使用数据步骤和 RETAIN 来创建您的值。使用 BY 语句和子集 IF 输出给定日期的所有值。

最后,按 DATE 降序排序,给你想要的顺序。

data have;
input Date   Amount   Type $;
datalines;
2015    15        A 
2014    -3        B 
2013     8        B 
2013    10        A 
2012     5        A 
;
run;

proc sort data=have;
by date;
run;

data want(keep=date a b);
set have;
by date;
retain a b;

if Type = "A" then
    a = amount;
else if Type = "B" then
    b = amount;

if last.date;
run;

proc sort data=want;
by descending date;
run;

这会产生: