如何使用 proc sql 实现 "Last. or First."
How to achieve "Last. or First." using proc sql
我正在尝试使用 Proc SQL 而不是数据步骤来实现 "last." 功能。假设我有如下数据集:
Account_Id Dept Salary Emp_Status Projects Rating
111 123 7000 Perm A 5
111 123 7000 Perm B 4
111 123 7000 Perm C 5
222 124 6000 Perm A 5
333 125 7000 Perm B 4
333 125 7000 Perm C 5
对于每个 account_id,我只希望输出中有一行。所以,我想要 last.account_id。我如何使用 proc sql 实现此目的?我尝试在 account_id 上分组时使用 max(monotnic()) 但没有用。
有人可以帮忙吗?此外,由于某些标准项目限制,我无法使用或执行子查询。在 proc sql?
中还有其他方法吗?
提前致谢!
假设您只关心输入数据集的行顺序而不是任何特定变量的值以确定分组内的顺序,以下内容似乎可以为您发布的示例数据执行您想要的操作:
data have;
input Account_Id Dept Salary Emp_Status $ Projects $ Rating;
cards;
111 123 7000 Perm A 5
111 123 7000 Perm B 4
111 123 7000 Perm C 5
222 124 6000 Perm A 5
333 125 7000 Perm B 4
333 125 7000 Perm C 5
;
run;
proc sql;
create table want as
select *, monotonic() as row_id from have
group by account_id
having row_id = max(row_id);
quit;
这似乎与您所说的已经尝试过的方法非常相似,因此如果它不起作用,请提供一些重现该问题的示例输入数据。
一般来说,我建议不要在生产代码中使用 monotonic()
,因为它没有记录,并且可能会在更复杂的查询中导致意外结果。使用 sql 时,您应该使用变量来定义行顺序。
您正确地指出在 SAS 中没有自动变量 SQL 等同于第一个。或最后。数据将需要具有支持明确的组内排序的列,这些列可用于 MAX 选择,然后用作连接条件。 Projects
在你的数据中是一个可能的候选人:
data have;
input Account_Id Dept Salary Emp_Status $ Projects $ Rating;
datalines;
111 123 7000 Perm A 5
111 123 7000 Perm B 4
111 123 7000 Perm C 5
222 124 6000 Perm A 5
333 125 7000 Perm B 4
333 125 7000 Perm C 5
run;
proc sql;
* standard sql query;
create table want as
select have.*
from have
join (select account_id, max(projects) as max_projects from have group by account_id) as matched
on matched.account_id = have.account_id
and matched.max_projects = have.projects
;
* SAS sql query that does magic auto remerge ;
create table want as
select have.*
from have
group by account_id
having projects = max(projects)
;
我会避免 monotonic()
,尤其是 SQL。该功能未记录,不保证在未来的版本中存在或执行等效。您的数据确实需要上下文列来选择组内极值。
我正在尝试使用 Proc SQL 而不是数据步骤来实现 "last." 功能。假设我有如下数据集:
Account_Id Dept Salary Emp_Status Projects Rating
111 123 7000 Perm A 5
111 123 7000 Perm B 4
111 123 7000 Perm C 5
222 124 6000 Perm A 5
333 125 7000 Perm B 4
333 125 7000 Perm C 5
对于每个 account_id,我只希望输出中有一行。所以,我想要 last.account_id。我如何使用 proc sql 实现此目的?我尝试在 account_id 上分组时使用 max(monotnic()) 但没有用。 有人可以帮忙吗?此外,由于某些标准项目限制,我无法使用或执行子查询。在 proc sql?
中还有其他方法吗?提前致谢!
假设您只关心输入数据集的行顺序而不是任何特定变量的值以确定分组内的顺序,以下内容似乎可以为您发布的示例数据执行您想要的操作:
data have;
input Account_Id Dept Salary Emp_Status $ Projects $ Rating;
cards;
111 123 7000 Perm A 5
111 123 7000 Perm B 4
111 123 7000 Perm C 5
222 124 6000 Perm A 5
333 125 7000 Perm B 4
333 125 7000 Perm C 5
;
run;
proc sql;
create table want as
select *, monotonic() as row_id from have
group by account_id
having row_id = max(row_id);
quit;
这似乎与您所说的已经尝试过的方法非常相似,因此如果它不起作用,请提供一些重现该问题的示例输入数据。
一般来说,我建议不要在生产代码中使用 monotonic()
,因为它没有记录,并且可能会在更复杂的查询中导致意外结果。使用 sql 时,您应该使用变量来定义行顺序。
您正确地指出在 SAS 中没有自动变量 SQL 等同于第一个。或最后。数据将需要具有支持明确的组内排序的列,这些列可用于 MAX 选择,然后用作连接条件。 Projects
在你的数据中是一个可能的候选人:
data have;
input Account_Id Dept Salary Emp_Status $ Projects $ Rating;
datalines;
111 123 7000 Perm A 5
111 123 7000 Perm B 4
111 123 7000 Perm C 5
222 124 6000 Perm A 5
333 125 7000 Perm B 4
333 125 7000 Perm C 5
run;
proc sql;
* standard sql query;
create table want as
select have.*
from have
join (select account_id, max(projects) as max_projects from have group by account_id) as matched
on matched.account_id = have.account_id
and matched.max_projects = have.projects
;
* SAS sql query that does magic auto remerge ;
create table want as
select have.*
from have
group by account_id
having projects = max(projects)
;
我会避免 monotonic()
,尤其是 SQL。该功能未记录,不保证在未来的版本中存在或执行等效。您的数据确实需要上下文列来选择组内极值。