SAS 在集合语句上的'/unique'实际上有什么作用?



我有一些旧的SAS代码要转换成python。

代码的一部分有效地做到了这一点:

data A (index=(key1=(record_id, record_version)));
set table.xxx (where = ...)
run;
data B;
set table.yyy (where = ...)
set A key=key1/unique;
if _ERROR_ = 1 then do;
valueA = "";
_ERROR_ = 0;
end;
run;

我已经阅读了SET和UNIQUE声明的文档,其中写道:

默认情况下,SET仅在KEY=值更改时才开始在索引顶部搜索。

如果KEY=值在SET语句的连续执行中没有更改,则搜索将从最近检索到的观测值开始。换句话说,当出现连续的重复KEY=值时,SET语句会尝试与正在读取的数据集中的重复索引值进行一对一匹配。如果指定的连续重复KEY=值比正在读取的数据集中存在的值多,则额外的重复项将被视为未找到。

当KEY=是唯一值时,只有第一次尝试读取具有该键值的观测值才成功;随后尝试用该键的值读取观察结果失败。IORC变量返回一个与SYSRC自动调用宏的助记符_DSENOM相对应的值。如果添加/UNIQUE选项,则随后尝试读取具有唯一KEY=值的观测值会成功。IORC变量返回一个0。

嗯,"随后尝试用该键的值读取观察结果失败&";。如何失败?

所以实际上,给定的A和B是:

A record_id record_version valueA     B record_id record_version valueB
1         1              A11          1         1              B10 
1         1              A12          1         2              B20
1         2              A22
1         3              A33 

我的输出肯定会包括以下几行:

record_id record_version valueA valueB
1         1              A11    B10
1         2              A22    B20

我不明白的是if _ERROR_语句的作用。

我明白了吗?

record_id record_version valueA valueB
1         1                     B10

还是这个?

record_id record_version valueA valueB
1         1              A12    B10

我明白了吗?

record_id record_version valueA valueB
1         3              A33    null

还是这个?

record_id record_version valueA valueB
1         3                     null

错误语句处理的边缘情况是什么?

set table.yyy (where = ...)数据中的键不在查找表A中时,代码将查找值重置为缺失。如果没有发生重置,则查找值将是从前一次成功查找中检索到的值。

如果存在不止一个可能的检索(即,查找表A具有record_id/record_version的重复(,则/UNIUE告诉SET它应该检索第一次查找。对于没有找到这样的查找的情况,仍然需要_ERROR_来重置查找值。

只有当主表具有重复关键字的行数多于非唯一索引查找表具有重复键的行数时,问题才会真正凸显出来。

示例:

* lookup indexed, but not unique;
* lookup is more typically a 'transaction' table;
data lookup(index=(IDX_key1key2=(key1 key2)));
input key1 key2 valueA $; datalines;
1 1 A11      1st 1 1
1 1 A12      2nd 1 1
1 2 A22
1 3 A33
;
data master;
input key1 key2 valueB $; datalines;
1 1 B10       1st 1 1 
1 2 B20
1 1 B30       1st 1 1 
1 1 B40       2nd 1 1
1 1 B50       3rd 1 1
;
* data for 2nd 1 1 lookup is from 2nd lookup;
* data for 3rd 1 1 lookup is from 2nd lookup and PUT will show _ERROR_=1 in log;
* No _ERROR_ check, that cant be good;
data master_with_keyed_lookup;
set b;
set a key=IDX_key1key2;
put _all_;
run;
* data retrieved for 2nd and 3rd 1 1 lookup are from 1st lookup row due to unique;
* No _ERROR_ check, that cant be good;
data master_with_unique_keyed_lookup;
set b;
set a key=IDX_key1key2/unique;
put _all_;
run;

最新更新