回填以下行详细信息

时间:2013-03-25 14:14:14

标签: sql sas

我有一个类似前3列的表,需要添加第四列:

Sequence ID Last Status  Current Status
1        1               New
2        1  New          Open    
3        1               Open
4        1               Open
5        1               Open
6        1  Open         Closed
7        1               Closed
8        1               Closed
9        1  Closed       
10       2               New
11       2  New          Open
12       2               Open
13       2  Open         Closed
14       2  Closed       
15       3               New
16       3  New          Open
etc.       

基本上它目前仅显示状态更改时的最后状态 - 我需要显示当前的“当前”状态。

我是SQL的新手,并且认为我可以使用LEAD,但遗憾的是SAS不支持它。

谢谢!

2 个答案:

答案 0 :(得分:2)

以下SQL适用于大多数方言,包括SAS SQL:

select t.quence, t.id, t.lastStatus, tnext.lastStatus as CurrentStatus
from (select t.*,
             (select min(Sequence) from t t2 where t2.id = t.id and t2.sequence > t.sequence and t2.LastStatus is not null
             ) as NextId
      from t
     ) t left out join
     t tnext
     on t.sequence = tnext.sequence

它找到具有相同id(如果有)的下一个状态记录,然后将结果重新加入以获取状态。

在SAS中,我更倾向于使用data step代码。如果数据存储在特定数据库中,则可能存在特定于数据库的更简单的解决方案。

答案 1 :(得分:2)

这是data step代码应该做你想要的。它没有正确执行最后一行,因为您没有任何进一步的行来指示它应该是Open。如果存在可以应用的数据逻辑规则,则应该易于添加。

它确实需要两种,这可能很昂贵,但SQL Join可能需要在幕后进行类似的操作。如果您有大量数据,我建议您测试两种方法,看看哪种方法更快。

data have;
input Sequence ID LastStatus  $;
infile datalines missover;
datalines;
1        1               
2        1  New           
3        1               
4        1               
5        1               
6        1  Open         
7        1               
8        1               
9        1  Closed       
10       2               
11       2  New          
12       2               
13       2  Open         
14       2  Closed       
15       3               
16       3  New          
;;;;
run;

proc sort data=have;
by id  descending sequence;
run;

data want;
set have;
length CurrentStatus $8;
by id  descending sequence;      *so the last sequence for each ID comes first;
retain CurrentStatus;            *keep its value for each row;
if first.id then 
 call missing(CurrentStatus);    *reset for each ID;
output;                          *put out the current line;
if not missing(LastStatus) then  
   CurrentStatus = LastStatus;   *now update CurrentStatus if needed;
run;

proc sort data=want;             *resort in logical order;
by id sequence;
run;