如何获得第二最大值和日期栏的第三最大记录在SAS

问题描述 投票:0回答:5

我想最大,第二最大值和第三最大值日期见下表的

proc SQL;

create table Kri_obs_l(
  Kri_rk int,
  value_dt datetime,
  score int
);

insert into Kri_obs_l
values (10000, "2Jan2018"d, 12)
values (10001, "2Jan2018"d, 2)
values (10001, "29Jan2019"d, 18)
values (10002, "2Jan2018"d, 5)
values (10002, "26Jan2019"d, 18)
values (10002, "27Jan2019"d, 18)
values (10003, "2Jan2018"d, 18)
values (10003, "26Jan2019"d, 18)
values (10003, "27Jan2019"d, 18)
values (10004, "2Jan2018"d, 25)
values (10005, "2Jan2018"d, 32)
values (10005, "26Jan2019"d, 18)
values (10005, "27Jan2019"d, 18)
values (10006, "2Jan2018"d, 5)
values (10007, "2Jan2018"d, 2)
values (10008, "2Jan2018"d, 12)
values (10009, "2Jan2018"d, 18)
values (10009, "26Jan2019"d, 18)
values (10009, "27Jan2019"d, 18)
;
quit;

我的代码,以获得最大,第二最大值和第三最大值

proc sql;
create table KRI_score_max as
select Kri_rk, MAX(value_dt) as reported_dt format=date9.
from KRI_OBS_l
group by Kri_rk;

create table KRI_score_second_max as
select Kri_rk, MAX(value_dt) as reported_dt format=date9.
from KRI_OBS_l a
where value_dt = (select MAX(value_dt) from KRI_OBS_l b where value_dt< (select MAX(value_dt) from KRI_OBS_l))
group by Kri_rk;

create table KRI_score_third_max as
select Kri_rk, MAX(value_dt) as reported_dt format=date9.
from KRI_OBS_l
where value_dt < (select MAX(value_dt) from KRI_OBS_l where value_dt< (select MAX(value_dt) from KRI_OBS_l))
group by Kri_rk;

create table KRI_score_third_max as
select * 
from KRI_score_third_max
where KRI_rk in (select Kri_rk from KRI_score_second_max);

quit;

获得最高记录工作的很好,我现在遇到的问题在得到第二最大值和第三最大值记录,如果我从它正常工作表中删除29Jan2019纪录,但补充说,记录使得27Jan2019第二最高记录,以便查询得到这个记录作为第二最大值。我想Kri_rk让每一个记录组的第二个最大和第三最高纪录。

由于没有在PROC SQL任何限制功能,我不能说明和限制使用的组合顺序。

sql sas sas-macro
5个回答
0
投票

简单PROC排名应该工作

proc rank data=Kri_obs_l out=inter descending ties=dense;
   by  Kri_rk;
  var value_dt ;
  ranks value_dt_1; 
 run; 

data final(drop=value_dt_1);
  set inter;
 if value_dt_1 le 3;
 run;

假设,如果你没有在每个ID重复日期然后在下面的查询应太

  proc sort data =Kri_obs_l out =Kri_obs_l_1;
     by  Kri_rk descending value_dt;
   run;

  data want;
    set Kri_obs_l_1;
  by  Kri_rk descending value_dt;
 if first.Kri_rk then m=1;
 else m+1;
   if m le 3;
 drop m;
   run;


   proc sql;
  create table want(drop=cnt) as 
     select Kri_rk, value_dt, score,
       (select count(value_dt) from Kri_obs_l a
    where a.Kri_rk = b.Kri_rk
   and a.value_dt ge b.value_dt
   group by Kri_rk) as cnt
   from Kri_obs_l b 
   where calculated cnt le 3
   ;

0
投票

您可以使用row_number()窗口功能,如果你想1日至3日最高

select * from 
(
select * ,row_number() over(partition by Kri_rk order by value_dt desc) rn
from table_name
) t where t.rn<=3

0
投票

你可以排除第一个创建的表会导致第二条语句,然后排除第三个查询前两个表。

proc sql;
create table KRI_score_max as
select Kri_rk, MAX(value_dt)  first_max as reported_dt format=date9.
from KRI_OBS_l
group by Kri_rk;

create table KRI_score_second_max as
select Kri_rk, MAX(value_dt) second_max as reported_dt  format=date9.
from KRI_OBS_l a
where (kri_rk, value_dt) not in (select kri_rk, first_max from KRI_score_max)
group by Kri_rk
UNION ALL 
select Kri_rk, MAX(value_dt) second_max as reported_dt format=date9. from KRI_OBS_l a group by Kri_rk having count(1)<2;

create table KRI_score_third_max as
select Kri_rk, MAX(value_dt) third_max as reported_dt format=date9.
from KRI_OBS_l
where (kri_rk, value_dt) not in (select kri_rk, first_max from KRI_score_maxl UNION ALL select kri_rk, second_max from KRI_score_second_max)
UNION ALL  
(select Kri_rk, MAX(value_dt) third_max as reported_dt format=date9. from KRI_OBS_l a group by Kri_rk having count(1)<3
MINUS
select Kri_rk,second_max from KRI_score_max); 

quit;

0
投票

当你正在使用SAS,然后利用在idgroupproc summary功能。下面的代码将存储前3日期每组,在单独的列(虽然你没有说清楚你到底想如何存储的数据)。

proc summary data=Kri_obs_l nway;
class kri_rk;
output out=want (drop=_:)
    idgroup(max(value_dt) out[3] (value_dt) = reported_dt);
run;

0
投票

有很多选项来解决这个问题。我优先再使用您的代码并调整你的PROC SQL。我运行下面的代码和它的工作了。

proc sql;
create table KRI_score_max as
select Kri_rk, MAX(value_dt) as reported_dt format=date9.
from KRI_OBS_l
group by Kri_rk;
quit;

proc sql;
create table KRI_score_second_max as
select a.Kri_rk, MAX(a.value_dt) as reported_dt format=date9.
from KRI_OBS_l a
where a.value_dt not in (Select reported_dt from Kri_score_max b where 
a.kri_rk=b.kri_rk)
group by a.Kri_rk;

quit;

proc sql;
create table KRI_score_third_max as
select a.Kri_rk, MAX(a.value_dt) as reported_dt format=date9.
from KRI_OBS_l a
where a.value_dt not in (Select reported_dt from Kri_score_max b where 
a.kri_rk=b.kri_rk) and 
a.value_dt not in (Select reported_dt from KRI_score_second_max b where 
a.kri_rk=b.kri_rk) 
group by a.Kri_rk;
quit;
© www.soinside.com 2019 - 2024. All rights reserved.