1

我有2个数据集如下

id name status 
1  A    a
2  B    b
3  C    c

另一个数据集

name status new
C    c      0
D    d      1
E    e      1
F    f      1

如何将第二个表中的所有行插入到第一个表中?情况是第一个表是永久性的。第二张表每月更新一次,所以我想将每月更新表中的所有行添加到永久表中,这样它看起来像这样

id name status
1  A    a
2  B    b
3  C    c
4  D    d
5  E    e
6  F    f

我面临的问题是我无法从数据集 1 中增加 id。据我搜索,SAS 中的数据集没有自动增量属性。自动增量可以通过使用数据步骤来完成,但我不知道数据步骤是否可以用于像这样的 2 个表的情况。通常的sql是

Insert into table1 (name, status) 
select name, status from table2 where new = 1;

但由于 sas 数据集不支持自动增量列,因此我面临的问题。我可以在上面的proc sql之后使用SAS数据步骤来解决它

data table1;
set table1;
if _n_ > 3 then id = _n_;
run;

这会增加 id 列的值,但代码有点丑,而且 id 是主键,在其他表中用作外键,所以我不想弄乱旧行的 id .

我正在学习和使用 SAS,因此非常感谢您的帮助。提前致谢。

额外问题:如果第二张表没有新列,有没有办法用数据步骤完成我想要的(从月度表(2nd)到永久表(1st)添加新行)?目前,我使用这个丑陋的 proc sql/data 步骤来创建新列

proc sql; //create a temp table from table2
create t2temp as select t2.*, 
(case when t2.name = t1.name and t2.status = t1.status then 0 else 1) as new
from table2 as t2 
left join table1 as t1
on t2.name = t1.name and t2.status = t1.status;
drop table t2; //drop the old table2 with no column "new"
quit;
data table2;  //rename the t2temp as table2
set t2temp;
run;
4

1 回答 1

3

您可以在数据步骤中执行此操作。顺便说一句,如果你完全重新创建它,你可以使用

id+1;

创建一个自动编号的字段(假设您的数据步骤不是太复杂)。这将跟踪当前的最高 ID 号,如果它在新数据集中,则随时为每一行分配一个更高的 ID。

data have;
input id name $ status $;
datalines;
2  A    a
3  B    b
1  C    c
;;;;
run;

data addon;
input name $ status $ new;
datalines;
C    c      0
D    d      1
E    e      1
F    f      1
;;;;
run;

data want;
retain _maxID;                    *keep the value of _maxID from one row to the next, 
                                   do not reset it;
set have(in=old) addon(in=add);   *in= creates a temporary variable indicating which 
                                   dataset a row came from;
if (old) or (add and new);        *in SAS like in c/etc., 0/missing(null) is 
                                   false negative/positive numbers are true;
if add then ID = _maxID+1;        *assigns ID to the new records;
_maxID = max(id,_maxID);          *determines the new maximum ID - 
                                   this structure guarantees it works 
                                   even if the old DS is not sorted;
put id= name=;
drop _maxID;
run;

回答第二个问题:

是的,你仍然可以这样做。最简单的方法之一是,如果您有按名称排序的数据集:

data want;
retain _maxID;
set have(in=old) addon(in=add);
by name;
if (old) or (add and first.name);
if add then ID = _maxID+1;
_maxID = max(id,_maxID);
put id= name=;
run;

对于具有相同值的第一条记录,first.name 为真name;因此,如果 HAVE 具有该名称的值,则不允许 ADDON 添加新记录。

这确实需要name在 HAVE 中是唯一的,否则您可能会删除一些记录。如果这不是真的,那么你有一个更复杂的解决方案。

于 2013-03-21T14:34:00.750 回答