0

我正在尝试使用宏程序来制作按总 GPA 排序的前 10% GPA 的记录,结果是 24 个最高 GPA,它们有超过 60 个学分但少于 130 个学分。这是我下面的代码

%MACRO TopTen(outputtable, less, more);
PROC SQL;
select round(count(ID)/10) into :Data from OverallGPA;
quit;

%PUT &Data;

PROC SQL outobs=&Data.;
    Create table &outputtable. as select * 
    from OverallGPA,OverallCreditHoursEarned
    where &less.<OverallCreditHoursEarned<&more.
    order by ID
;
quit;

%MEND;

%TopTen(Report3, 60, 130);
/* creates report of number of values in top ten percent */
PROC REPORT data=Report3;
run;

此 Proc 报告当前正在打印具有相同 ID、TotalGPA 但不同的OverallCreditHoursEarned 的列。有什么想法可以完成这项工作吗?我使用了我认为可行但不适用于宏的 Proc Rank。Proc Rank代码如下。

   PROC RANK data=OverallGPA out=Report3Alt(where=(TopTenPercent<=24)) 
   descending ties=Low;
   var TotalGPA;
   ranks TopTenPercent;
   run;
4

1 回答 1

2

你的 SQL 连接没有做你想做的事。这:

from OverallGPA, OverallCreditHoursEarned
where &less. <  OverallCreditHoursEarned < &more

这不会告诉 SAS(或 SQL)将这两个表连接到什么上,因此它将每个表中的每条记录连接到另一个表中的每条记录。如果您在 1 个表中有 100 条记录,而在另一个表中有 100 条记录,它将在输出表中生成 10,000 条记录。这不是你想要的。

首先,我强烈建议简单地使用PROC RANK它,因为这就是它的工作。您正在为 SAS 付费,在有意义的时候使用 SAS。把它放在你有主 PROC SQL 连接的宏中。或者,使用GROUPSPROC RANK 中的选项,它将您的记录分组为十分位数(或其他),并过滤输出数据集WHERE GROUP=0或任何适合您需要的内容。这可能有效:

PROC RANK data=OverallGPA out=Report3Alt(where=(TopTenPercent=0)) groups=10 
   descending ties=Low;
   var TotalGPA;
   ranks TopTenPercent;
   run;

但是,如果您想使用 SQL,请正确连接 - 使用带有on语句的显式连接,或者使用 ID 变量将相等添加到您的where语句中。我更喜欢用语句显式连接on,所以像

from OverallGPA inner join OverallCreditHours 
on OverallGPA.ID = OverallCreditHours.ID
where OverallCreditHours.OverallCreditHours between &less and &more

或同等学历。您可能想要左连接或右连接,我不清楚,但内部似乎最有可能。

于 2021-04-15T05:44:03.743 回答