Proc sql - 在主查询中通过子查询的聚合函数进行分组

时间:2017-03-03 10:33:45

标签: sas enterprise-guide

我有两个包含数百万行的数据集。表1包含两个不同的ID号,ID1和ID2。它还包含一个变量,用于解释某个ID所属的组(变量y1)。

第二个表(表2)包含第一个表中的两个变量和另一个变量。

我想将两个表连接在一起,但在连接之前,我希望table1只包含按ID1分组的信息,并且还要为我提供ID属于哪个组的信息。

我可以在两个Proc Sql阶段中执行此操作,其中我首先在table1上创建一个表,其中我按ID1分组,然后创建另一个步骤,我将其合并到table2上。然而,这是相当低效的,因为我的表包含很多行,因此我想在一次运行中执行此操作。因此我创建了一个子查询来完成我想要的。我的问题是我得到的错误是我不能按变量"哪个组"来自我的子查询,因为它源于一个聚合函数。我想知道我想要实现的目标是否有一些好的解决方法?

非常感谢提前!

示例代码:

data table1;
input ID1 $ ID2 $ x1 2. y1 $;
datalines;
1 p1 10 Group1
1 p2 20 Group2
2 p3 50 Group1
;
run;

data table2;
input ID1 $ x1 x2;
datalines;
1 10 500
1 20 600
2 50 700
;
run;


Proc sql;
    Create table Test
      as select
        t1.WhichGroup
        ,sum(t1.Sum_x1) as Sum_x1
        ,sum(t2.x2) as Sum_x2
          from (select 
                    a.ID1
                    ,case when max(case when a.y1 = 'Group1' then 1 else 0 end) = 0 then 'Group2'
                          when max(case when a.y1 = 'Group2' then 1 else 0 end) = 0 then 'Group1'
                          else 'Both' end as WhichGroup
                    ,Sum(a.x1) as Sum_x1
                  from work.table1  as a
                 group by 1
                ) as t1
            left join 
               work.table2   as t2
        on t1.ID1 = t2.ID1
    Group by 1;
Quit;

1 个答案:

答案 0 :(得分:0)

- 回答我自己的问题 -

我不确定为什么会这样,但我遇到了非常感兴趣的现象,可能是SAS中的一个错误。

看起来查询不起作用的全部原因是因为如果以数字形式给出SAS而不是明确说明要分组的变量名,则SAS不理解group by语句。可能SAS在列顺序中丢失了吗?

有没有其他人在SAS之前遇到过这种现象?

因此,如果使用以下代码,则查询有效:

Proc sql;
    Create table Test
      as select
        t1.WhichGroup
        ,sum(t1.Sum_x1) as sum_x1
        ,sum(t2.x2) as Sum_x2
          from (select 
                    a.ID1
                    ,case when max(case when a.y1 = 'Group1' then 1 else 0 end) = 0 then 'Group2'
                          when max(case when a.y1 = 'Group2' then 1 else 0 end) = 0 then 'Group1'
                          else 'Both' end as WhichGroup
                    ,Sum(a.x1) as Sum_x1
                  from work.table1  as a
                 group by 1
                ) as t1
            left join 
               work.table2   as t2
        on t1.ID1 = t2.ID1
    Group by WhichGroup;
Quit;