如何从最小和最大分组中获取日期?

时间:2018-10-10 14:13:25

标签: sql sas

我是SAS开发人员。 我有一个sql可以通过从名为“ CalculatedPower”的列获取最小值和最大值进行分组。 下面是我从一组陈述中得到的结构 (我想要的是lt_dt和lp_dt。我将其放在此处,但它不在我的实际表中,因为我不知道该如何实现) :

station datetime        calculatedpower min_power   max_power   lt_dt               lp_dt
ABBA    28AUG2018:0:0:0     100         1            100        01SEP2018:1:0:0     28AUG2018:0:0:0
ABBA    31AUG2018:12:0:0    88          1            100        01SEP2018:1:0:0     28AUG2018:0:0:0
ABBA    01SEP2018:1:0:0     1           1            100        01SEP2018:1:0:0     28AUG2018:0:0:0
ZZZZ    07SEP2018:0:0:0     900         900          3000       07SEP2018:0:0:0     21SEP2018:0:0:0
ZZZZ    09SEP2018:0:0:0     1000        900          3000       07SEP2018:0:0:0     21SEP2018:0:0:0
ZZZZ    21SEP2018:0:0:0     3000        900          3000       07SEP2018:0:0:0     21SEP2018:0:0:0

正如大家所看到的,我按站聚合它们,并使用Min和Max函数获得min_power和max_power。现在,我还需要获取最小日期时间(进入lt_dt)和最大日期时间(进入lp_dt)。 我期望如下所示: ABBA lt_dt为01SEP2018:1:0:0,而lp_dt为28AUG2018:0:0:0

意思是lp_dt(基于最大功率的日期时间)而lt_dt(基于最小功率的日期时间)

我的分组依据如下:

proc sql;
select 
station
,datetime
,calculatedpower
,min(calculatedpower) as lt_calculatedpower
,max(calculatedpower) as lp_calculatedpower
from sumall
group by 
station
;
quit;

是否可以调整现有的SQL语句以实现所需的日期时间? 我尝试了如下所示的其他SQL语句(但是它花了永久的时间处理600k数据,不确定它是否仍在运行,因为它仍在运行)

proc sql;
select *,
case when calculatedpower=lt_calculatedpower then datetime end as lt_datetime
from minmax;
quit;

使用此代码,我预见到如果有几行具有相同的计算能力但不同的日期时间绑定到1个站,则会出现问题。

2 个答案:

答案 0 :(得分:1)

在SQL中,您将需要使用包含case语句的子选择,该case语句标识出现最大值和最小值的日期。子选择已联接到原始表。

注意:SAS SQL将在适当的时候自动重新加入摘要(聚合函数)结果。

示例

在此示例中,level1_id代表stationlevel2_seq代表datetime,而x代表calculatedpower

data have;
  do level1_id = 1 to 5;
    do level2_seq = 1 to 5;
      x = floor(100*ranuni(123));
      output;
    end;
  end;
run;

proc sql;
  create table want as
  select 
    have.*
    , min(have.x) as min_x
    , max(have.x) as max_x
    , min(at.min_at) as min_x_first_at_seq
    , min(at.max_at) as max_x_first_at_seq
  from 
    have
  left join 
  (
    select inside.level1_id, inside.level2_seq
    , case when inside.x = min(inside.x) then inside.level2_seq else . end as min_at
    , case when inside.x = max(inside.x) then inside.level2_seq else . end as max_at
    from have inside
    group by inside.level1_id
  ) at
  on
    have.level1_id = at.level1_id and
    have.level2_seq = at.level2_seq
  group by
    have.level1_id
  order by
    have.level1_id, level2_seq
  ;

答案 1 :(得分:1)

这是SAS PROC Summary和DATA STEP合并以获得最终所需的输出。

使用OUTPUT语句上的MAXID,MINID选项来获取最大值的ID和最小值的ID。

解决方案的第一部分将生成您的虚假数据-以后请以这种格式提供数据。然后,PROC Summary计算统计信息,然后可以将其合并。这应该在您的系统上非常迅速地完成,不到一分钟。

data have;
input station $ datetime  anydtdtm.      calculatedpower ;
format datetime datetime.;
cards;
ABBA    28AUG2018:0:0:0     100         
ABBA    31AUG2018:12:0:0    88          
ABBA    01SEP2018:1:0:0     1           
ZZZZ    07SEP2018:0:0:0     900         
ZZZZ    09SEP2018:0:0:0     1000        
ZZZZ    21SEP2018:0:0:0     3000        
;;;;
run;

proc summary data=have nway;
class station;
id datetime;
var calculatedPower;
output out=summary min=Min_power max=max_power minid=min_date  maxid=max_Date;
run;

data final;
merge have summary;
by station;
run;

编辑:删除了自动命名选项,因为我明确命名了输出变量。

EDIT2: 当多个观测值在所有MIN或MAX变量中都包含相同的极值时,PROC MEANS将使用观测值编号解析将哪个观测值写入输出。 默认情况下,PROC MEANS使用第一个观测值解决任何联系。但是,如果指定LAST选项,则PROC MEANS使用最后一个观测值解决任何联系。

https://documentation.sas.com/?docsetId=proc&docsetTarget=p04vbvpcjg2vrjn1v8wyf0daypfi.htm&docsetVersion=9.4&locale=en#p1p58yhxlrc0can1scam7bco7y96