簡體   English   中英

SAS數據步/ proc sql使用自動增量主鍵從另一個表插入行

[英]SAS data step/ proc sql insert rows from another table with auto increment primary key

我有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

如何將第2個表中的所有行插入第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,所以非常感謝幫助。 提前致謝。

額外的問題:如果第二個表沒有新列,有沒有辦法用數據步驟完成我想要的東西(從月表(第二個)到永久表(第一個)添加新行)? 目前,我使用這個丑陋的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;

你可以在datastep中完成。 順便說一句,如果你完全重新創建它,你可以使用

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;

回答第二個問題:

是的,你仍然可以這樣做。 最簡單的方法之一是,如果您有按NAME排序的數據集:

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;

對於具有相同name值的第一條記錄,first.name將為true; 因此,如果HAVE具有該名稱的值,則不允許ADDON添加新記錄。

這確實要求name在HAVE中是唯一的,或者您可能刪除一些記錄。 如果不是這樣,那么你有一個更復雜的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM