我有一个必须根据粒度(FIELD1和FIELD2)汇总的数据集。必须对两个指标字段(METRIC1和METRIC2)进行汇总。到目前为止,这似乎是一个简单的GROUP BY任务。但是我有一个字符串字段(FLAG),也必须通过串联不同的值来汇总。
可以在Oracle中使用LISTAGG()函数执行此操作。 请帮助我在SAS Proc SQL中实现相同的目标。
答案 0 :(得分:2)
我不认为在SAS中有直接的方法。 CATS(和类似的串联功能)不是聚合功能。有人建议将这些添加回几年前,但我所知道的什么都没有(请参阅this thread。)
如果我理解正确,您正在做的是GROUP BY field1 / field2,SUM metric1 / metric2,并创建一个将所有可见的FLAG字段值(但不按其分组)的FLAG字段。
我要处理的方式是先进行聚合(field1 / field2),然后将其加入到单独的表中,该表只是field1 / field2 / flag。您可以在数据步骤中最轻松地做到这一点,例如:
data want;
set have;
by field1 field2;
length flag_out $100; *or longer if you need longer;
flag_out = catx(',',flag_out,flag);
if last.field2 then output;
rename flag_out=flag;
drop flag;
run;
这假设它已经按field1 / field2进行了排序,否则您需要先进行此操作。
答案 1 :(得分:1)
如上所述,没有LISTAGG()
函数,也没有用于创建自定义聚合函数的内置功能。但是,有两种可能性可以得到输出。
示例一
具有DOW处理和散列的数据步骤,用于在组内并置时跟踪不同的标志值。
data want;
if 0 then set have; *prep pdv;
length flags $200;
declare hash _flags();
_flags.defineKey('flag');
_flags.defineDone();
do until (last.f2);
set have;
by f1 f2;
m1_sum = sum(m1_sum,m1);
m2_sum = sum(m2_sum,m2);
if _flags.find() ne 0 then do;
_flags.add();
flags = catx(',',flags,flag);
end;
end;
drop m1 m2 flag;
_flags.delete();
run;
示例二
创建从SQL内部使用的FCMP自定义函数。由于FCMP无法创建聚合函数,因此结果将自动与原始数据合并,然后必须对其进行过滤。 FCMP函数还使用散列来跟踪组中flag
的不同值。
proc fcmp outlib=sasuser.functionsx.package;
function listagg(f1 $, f2 $, n, item $) $;
length result $32000 index 8;
static flag;
static index;
declare hash items();
if flag = . then do;
flag = 1;
rc = items.defineKey('item');
rc = items.defineDone();
end;
static items;
index + 1;
rc = items.replace();
if index = n then do;
declare hiter hi('items');
result = '';
do while (hi.next() = 0);
result = catx(',',result,item);
end;
index = 0;
rc = items.clear();
return (result);
end;
else
return ("");
endsub;
run;
options cmplib=sasuser.functionsx;
proc sql;
create table wanted as
select * from
(
select /* subselect is a remerge due to 'listagg' mimic */
f1,
f2,
listagg(f1, f2, count(*), flag) as flags,
sum(m1) as m1,
sum(m2) as m2
from have
group by f1, f2
)
where flags is not null /* filter the subselect */
;
quit;
理想情况下,将使用哈希哈希,但是FCMP仅在declare
语句中提供哈希实例的创建,而动态哈希不能用_new_
实例化。 SAS Viya用户将能够在FCMP功能中使用新的组件对象Dictionary
,并且可能具有字典词典来跟踪每个组中不同的标志值。 / p>
答案 2 :(得分:0)
感谢大家的宝贵意见。显然,SAS中没有针对此方案的直接解决方案。考虑到需求的整体情况,我决定在数据层本身解决问题,或添加另一个中间表示层。 我敢肯定,很多人已经指出了SAS的这一需求,我也曾提出过SAS这个问题。希望他们研究一下并提出与LISTAGG或GROUP_CONCAT类似的功能。